1 /*****************************************************************************
2  *
3  * XODTEMPLATE.C - Template-based object configuration data input routines
4  *
5  * Copyright (c) 2001-2009 Ethan Galstad (egalstad@nagios.org)
6  * Last Modified: 01-01-2009
7  *
8  * Description:
9  *
10  * Routines for parsing and resolving template-based object definitions.
11  * Basic steps involved in this in the daemon are as follows:
12  *
13  *    1) Read
14  *    2) Resolve
15  *    3) Duplicate
16  *    4) Recombobulate
17  *    5) Cache
18  *    7) Register
19  *    8) Cleanup
20  *
21  * The steps involved for the CGIs differ a bit, since they read the cached
22  * definitions which are already resolved, recombobulated and duplicated.  In
23  * otherwords, they've already been "flattened"...
24  *
25  *    1) Read
26  *    2) Register
27  *    3) Cleanup
28  *
29  *
30  * License:
31  *
32  * This program is free software; you can redistribute it and/or modify
33  * it under the terms of the GNU General Public License version 2 as
34  * published by the Free Software Foundation.
35  *
36  * This program is distributed in the hope that it will be useful,
37  * but WITHOUT ANY WARRANTY; without even the implied warranty of
38  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
39  * GNU General Public License for more details.
40  *
41  * You should have received a copy of the GNU General Public License
42  * along with this program; if not, write to the Free Software
43  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
44  *
45  *****************************************************************************/
46 
47 
48 /*********** COMMON HEADER FILES ***********/
49 
50 #include "../include/config.h"
51 #include "../include/common.h"
52 #include "../include/objects.h"
53 #include "../include/locations.h"
54 #include "../include/macros.h"
55 #include "../include/skiplist.h"
56 
57 /**** CORE OR CGI SPECIFIC HEADER FILES ****/
58 
59 #ifdef NSCORE
60 #include "../include/nagios.h"
61 #endif
62 
63 #ifdef NSCGI
64 #include "../include/cgiutils.h"
65 #endif
66 
67 /**** DATA INPUT-SPECIFIC HEADER FILES ****/
68 
69 #include "xodtemplate.h"
70 
71 
72 #ifdef NSCORE
73 extern int use_regexp_matches;
74 extern int use_true_regexp_matching;
75 extern int verify_config;
76 extern int test_scheduling;
77 extern int use_precached_objects;
78 #endif
79 
80 xodtemplate_timeperiod *xodtemplate_timeperiod_list = NULL;
81 xodtemplate_command *xodtemplate_command_list = NULL;
82 xodtemplate_contactgroup *xodtemplate_contactgroup_list = NULL;
83 xodtemplate_hostgroup *xodtemplate_hostgroup_list = NULL;
84 xodtemplate_servicegroup *xodtemplate_servicegroup_list = NULL;
85 xodtemplate_servicedependency *xodtemplate_servicedependency_list = NULL;
86 xodtemplate_serviceescalation *xodtemplate_serviceescalation_list = NULL;
87 xodtemplate_contact *xodtemplate_contact_list = NULL;
88 xodtemplate_host *xodtemplate_host_list = NULL;
89 xodtemplate_service *xodtemplate_service_list = NULL;
90 xodtemplate_hostdependency *xodtemplate_hostdependency_list = NULL;
91 xodtemplate_hostescalation *xodtemplate_hostescalation_list = NULL;
92 xodtemplate_hostextinfo *xodtemplate_hostextinfo_list = NULL;
93 xodtemplate_serviceextinfo *xodtemplate_serviceextinfo_list = NULL;
94 
95 xodtemplate_timeperiod *xodtemplate_timeperiod_list_tail = NULL;
96 xodtemplate_command *xodtemplate_command_list_tail = NULL;
97 xodtemplate_contactgroup *xodtemplate_contactgroup_list_tail = NULL;
98 xodtemplate_hostgroup *xodtemplate_hostgroup_list_tail = NULL;
99 xodtemplate_servicegroup *xodtemplate_servicegroup_list_tail = NULL;
100 xodtemplate_servicedependency *xodtemplate_servicedependency_list_tail = NULL;
101 xodtemplate_serviceescalation *xodtemplate_serviceescalation_list_tail = NULL;
102 xodtemplate_contact *xodtemplate_contact_list_tail = NULL;
103 xodtemplate_host *xodtemplate_host_list_tail = NULL;
104 xodtemplate_service *xodtemplate_service_list_tail = NULL;
105 xodtemplate_hostdependency *xodtemplate_hostdependency_list_tail = NULL;
106 xodtemplate_hostescalation *xodtemplate_hostescalation_list_tail = NULL;
107 xodtemplate_hostextinfo *xodtemplate_hostextinfo_list_tail = NULL;
108 xodtemplate_serviceextinfo *xodtemplate_serviceextinfo_list_tail = NULL;
109 
110 
111 skiplist *xobject_template_skiplists[NUM_XOBJECT_SKIPLISTS];
112 skiplist *xobject_skiplists[NUM_XOBJECT_SKIPLISTS];
113 
114 
115 void *xodtemplate_current_object = NULL;
116 int xodtemplate_current_object_type = XODTEMPLATE_NONE;
117 
118 int xodtemplate_current_config_file = 0;
119 char **xodtemplate_config_files = NULL;
120 
121 char *xodtemplate_cache_file = NULL;
122 char *xodtemplate_precache_file = NULL;
123 
124 int presorted_objects = FALSE;
125 
126 extern int allow_empty_hostgroup_assignment;
127 
128 /*
129  * Macro magic used to determine if a service is assigned
130  * via hostgroup_name or host_name. Those assigned via host_name
131  * take precedence.
132  */
133 #define X_SERVICE_IS_FROM_HOSTGROUP      (1 << 1)  /* flag to know if service come from a hostgroup def, apply on srv->have_initial_state */
134 #define xodtemplate_set_service_is_from_hostgroup(srv) \
135 	srv->have_initial_state |= X_SERVICE_IS_FROM_HOSTGROUP
136 #define xodtemplate_unset_service_is_from_hostgroup(srv) \
137 	srv->have_initial_state &= ~X_SERVICE_IS_FROM_HOSTGROUP
138 #define xodtemplate_is_service_is_from_hostgroup(srv) \
139 	((srv->have_initial_state & X_SERVICE_IS_FROM_HOSTGROUP) != 0)
140 
141 
142 
143 /* returns the name of a numbered config file */
xodtemplate_config_file_name(int config_file)144 static char *xodtemplate_config_file_name(int config_file) {
145 	if(config_file <= xodtemplate_current_config_file)
146 		return xodtemplate_config_files[config_file - 1];
147 
148 	return "?";
149 	}
150 
151 
152 
153 /******************************************************************/
154 /************* TOP-LEVEL CONFIG DATA INPUT FUNCTION ***************/
155 /******************************************************************/
156 
157 /* process all config files - both core and CGIs pass in name of main config file */
xodtemplate_read_config_data(char * main_config_file,int options,int cache,int precache)158 int xodtemplate_read_config_data(char *main_config_file, int options, int cache, int precache) {
159 #ifdef NSCORE
160 	char *config_file = NULL;
161 	char *config_base_dir = NULL;
162 	char *input = NULL;
163 	char *var = NULL;
164 	char *val = NULL;
165 	struct timeval tv[14];
166 	double runtime[14];
167 	mmapfile *thefile = NULL;
168 #endif
169 	int result = OK;
170 
171 
172 	if(main_config_file == NULL) {
173 #ifdef NSCORE
174 		printf("Error: No main config file passed to object routines!\n");
175 #endif
176 		return ERROR;
177 		}
178 
179 	/* get variables from main config file */
180 	xodtemplate_grab_config_info(main_config_file);
181 
182 	/* initialize variables */
183 	xodtemplate_timeperiod_list = NULL;
184 	xodtemplate_command_list = NULL;
185 	xodtemplate_contactgroup_list = NULL;
186 	xodtemplate_hostgroup_list = NULL;
187 	xodtemplate_servicegroup_list = NULL;
188 	xodtemplate_servicedependency_list = NULL;
189 	xodtemplate_serviceescalation_list = NULL;
190 	xodtemplate_contact_list = NULL;
191 	xodtemplate_host_list = NULL;
192 	xodtemplate_service_list = NULL;
193 	xodtemplate_hostdependency_list = NULL;
194 	xodtemplate_hostescalation_list = NULL;
195 	xodtemplate_hostextinfo_list = NULL;
196 	xodtemplate_serviceextinfo_list = NULL;
197 
198 	/* initialize skiplists */
199 	xodtemplate_init_xobject_skiplists();
200 
201 	xodtemplate_current_object = NULL;
202 	xodtemplate_current_object_type = XODTEMPLATE_NONE;
203 
204 	/* allocate memory for 256 config files (increased dynamically) */
205 	xodtemplate_current_config_file = 0;
206 	xodtemplate_config_files = (char **)malloc(256 * sizeof(char **));
207 	if(xodtemplate_config_files == NULL) {
208 #ifdef NSCORE
209 		printf("Unable to allocate memory!\n");
210 #endif
211 		return ERROR;
212 		}
213 
214 	/* are the objects we're reading already pre-sorted? */
215 	presorted_objects = FALSE;
216 #ifdef NSCORE
217 	presorted_objects = (use_precached_objects == TRUE) ? TRUE : FALSE;
218 #endif
219 
220 #ifdef NSCORE
221 	if(test_scheduling == TRUE)
222 		gettimeofday(&tv[0], NULL);
223 
224 	/* only process the precached object file as long as we're not regenerating it and we're not verifying the config */
225 	if(use_precached_objects == TRUE)
226 		result = xodtemplate_process_config_file(xodtemplate_precache_file, options);
227 
228 	/* process object config files normally... */
229 	else {
230 
231 		/* determine the directory of the main config file */
232 		if((config_file = (char *)strdup(main_config_file)) == NULL) {
233 			my_free(xodtemplate_config_files);
234 #ifdef NSCORE
235 			printf("Unable to allocate memory!\n");
236 #endif
237 			return ERROR;
238 			}
239 		config_base_dir = (char *)strdup(dirname(config_file));
240 		my_free(config_file);
241 
242 		/* open the main config file for reading (we need to find all the config files to read) */
243 		if((thefile = mmap_fopen(main_config_file)) == NULL) {
244 			my_free(config_base_dir);
245 			my_free(xodtemplate_config_files);
246 #ifdef NSCORE
247 			printf("Unable to open main config file '%s'\n", main_config_file);
248 #endif
249 			return ERROR;
250 			}
251 
252 		/* daemon reads all config files/dirs specified in the main config file */
253 		/* read in all lines from the main config file */
254 		while(1) {
255 
256 			/* free memory */
257 			my_free(input);
258 
259 			/* get the next line */
260 			if((input = mmap_fgets_multiline(thefile)) == NULL)
261 				break;
262 
263 			/* strip input */
264 			strip(input);
265 
266 			/* skip blank lines and comments */
267 			if(input[0] == '#' || input[0] == ';' || input[0] == '\x0')
268 				continue;
269 
270 			if((var = strtok(input, "=")) == NULL)
271 				continue;
272 
273 			if((val = strtok(NULL, "\n")) == NULL)
274 				continue;
275 
276 			/* process a single config file */
277 			if(!strcmp(var, "xodtemplate_config_file") || !strcmp(var, "cfg_file")) {
278 
279 				if(config_base_dir != NULL && val[0] != '/') {
280 					asprintf(&config_file, "%s/%s", config_base_dir, val);
281 					}
282 				else
283 					config_file = strdup(val);
284 
285 				/* process the config file... */
286 				result = xodtemplate_process_config_file(config_file, options);
287 
288 				my_free(config_file);
289 
290 				/* if there was an error processing the config file, break out of loop */
291 				if(result == ERROR)
292 					break;
293 				}
294 
295 			/* process all files in a config directory */
296 			else if(!strcmp(var, "xodtemplate_config_dir") || !strcmp(var, "cfg_dir")) {
297 
298 				if(config_base_dir != NULL && val[0] != '/') {
299 					asprintf(&config_file, "%s/%s", config_base_dir, val);
300 					}
301 				else
302 					config_file = strdup(val);
303 
304 				/* strip trailing / if necessary */
305 				if(config_file != NULL && config_file[strlen(config_file) - 1] == '/')
306 					config_file[strlen(config_file) - 1] = '\x0';
307 
308 				/* process the config directory... */
309 				result = xodtemplate_process_config_dir(config_file, options);
310 
311 				my_free(config_file);
312 
313 				/* if there was an error processing the config file, break out of loop */
314 				if(result == ERROR)
315 					break;
316 				}
317 			}
318 
319 		/* free memory and close the file */
320 		my_free(config_base_dir);
321 		my_free(input);
322 		mmap_fclose(thefile);
323 		}
324 
325 	if(test_scheduling == TRUE)
326 		gettimeofday(&tv[1], NULL);
327 #endif
328 
329 #ifdef NSCGI
330 	/* CGIs process only one file - the cached objects file */
331 	result = xodtemplate_process_config_file(xodtemplate_cache_file, options);
332 #endif
333 
334 #ifdef NSCORE
335 
336 	/* only perform intensive operations if we're not using the precached object file */
337 	if(use_precached_objects == FALSE) {
338 
339 		/* resolve objects definitions */
340 		if(result == OK)
341 			result = xodtemplate_resolve_objects();
342 		if(test_scheduling == TRUE)
343 			gettimeofday(&tv[2], NULL);
344 
345 		/* cleanup some additive inheritance stuff... */
346 		xodtemplate_clean_additive_strings();
347 
348 		/* do the meat and potatoes stuff... */
349 		if(result == OK)
350 			result = xodtemplate_recombobulate_contactgroups();
351 		if(test_scheduling == TRUE)
352 			gettimeofday(&tv[3], NULL);
353 
354 		if(result == OK)
355 			result = xodtemplate_recombobulate_hostgroups();
356 		if(test_scheduling == TRUE)
357 			gettimeofday(&tv[4], NULL);
358 
359 		if(result == OK)
360 			result = xodtemplate_duplicate_services();
361 		if(test_scheduling == TRUE)
362 			gettimeofday(&tv[5], NULL);
363 
364 		if(result == OK)
365 			result = xodtemplate_recombobulate_servicegroups();
366 		if(test_scheduling == TRUE)
367 			gettimeofday(&tv[6], NULL);
368 
369 		if(result == OK)
370 			result = xodtemplate_duplicate_objects();
371 		if(test_scheduling == TRUE)
372 			gettimeofday(&tv[7], NULL);
373 
374 		/* NOTE: some missing defaults (notification options, etc.) are also applied here */
375 		if(result == OK)
376 			result = xodtemplate_inherit_object_properties();
377 		if(test_scheduling == TRUE)
378 			gettimeofday(&tv[8], NULL);
379 
380 		if(result == OK)
381 			result = xodtemplate_recombobulate_object_contacts();
382 		if(test_scheduling == TRUE)
383 			gettimeofday(&tv[9], NULL);
384 
385 		/* sort objects */
386 		if(result == OK)
387 			result = xodtemplate_sort_objects();
388 		if(test_scheduling == TRUE)
389 			gettimeofday(&tv[10], NULL);
390 		}
391 
392 	if(result == OK) {
393 
394 		/* merge host/service extinfo definitions with host/service definitions */
395 		/* this will be removed in Nagios 4.x */
396 		xodtemplate_merge_extinfo_ojects();
397 
398 		/* cache object definitions for the CGIs and external apps */
399 		if(cache == TRUE)
400 			xodtemplate_cache_objects(xodtemplate_cache_file);
401 
402 		/* precache object definitions for future runs */
403 		if(precache == TRUE)
404 			xodtemplate_cache_objects(xodtemplate_precache_file);
405 		}
406 
407 	if(test_scheduling == TRUE)
408 		gettimeofday(&tv[11], NULL);
409 
410 #endif
411 
412 	/* register objects */
413 	if(result == OK)
414 		result = xodtemplate_register_objects();
415 #ifdef NSCORE
416 	if(test_scheduling == TRUE)
417 		gettimeofday(&tv[12], NULL);
418 #endif
419 
420 	/* cleanup */
421 	xodtemplate_free_memory();
422 #ifdef NSCORE
423 	if(test_scheduling == TRUE)
424 		gettimeofday(&tv[13], NULL);
425 #endif
426 
427 	/* free memory */
428 	my_free(xodtemplate_cache_file);
429 	my_free(xodtemplate_precache_file);
430 
431 #ifdef NSCORE
432 	if(test_scheduling == TRUE) {
433 
434 		runtime[0] = (double)((double)(tv[1].tv_sec - tv[0].tv_sec) + (double)((tv[1].tv_usec - tv[0].tv_usec) / 1000.0) / 1000.0);
435 		if(use_precached_objects == FALSE) {
436 			runtime[1] = (double)((double)(tv[2].tv_sec - tv[1].tv_sec) + (double)((tv[2].tv_usec - tv[1].tv_usec) / 1000.0) / 1000.0);
437 			runtime[2] = (double)((double)(tv[3].tv_sec - tv[2].tv_sec) + (double)((tv[3].tv_usec - tv[2].tv_usec) / 1000.0) / 1000.0);
438 			runtime[3] = (double)((double)(tv[4].tv_sec - tv[3].tv_sec) + (double)((tv[4].tv_usec - tv[3].tv_usec) / 1000.0) / 1000.0);
439 			runtime[4] = (double)((double)(tv[5].tv_sec - tv[4].tv_sec) + (double)((tv[5].tv_usec - tv[4].tv_usec) / 1000.0) / 1000.0);
440 			runtime[5] = (double)((double)(tv[6].tv_sec - tv[5].tv_sec) + (double)((tv[6].tv_usec - tv[5].tv_usec) / 1000.0) / 1000.0);
441 			runtime[6] = (double)((double)(tv[7].tv_sec - tv[6].tv_sec) + (double)((tv[7].tv_usec - tv[6].tv_usec) / 1000.0) / 1000.0);
442 			runtime[7] = (double)((double)(tv[8].tv_sec - tv[7].tv_sec) + (double)((tv[8].tv_usec - tv[7].tv_usec) / 1000.0) / 1000.0);
443 			runtime[8] = (double)((double)(tv[9].tv_sec - tv[8].tv_sec) + (double)((tv[9].tv_usec - tv[8].tv_usec) / 1000.0) / 1000.0);
444 			runtime[9] = (double)((double)(tv[10].tv_sec - tv[9].tv_sec) + (double)((tv[10].tv_usec - tv[9].tv_usec) / 1000.0) / 1000.0);
445 			runtime[10] = (double)((double)(tv[11].tv_sec - tv[10].tv_sec) + (double)((tv[11].tv_usec - tv[10].tv_usec) / 1000.0) / 1000.0);
446 			runtime[11] = (double)((double)(tv[12].tv_sec - tv[11].tv_sec) + (double)((tv[12].tv_usec - tv[11].tv_usec) / 1000.0) / 1000.0);
447 			}
448 		else {
449 			runtime[1] = 0.0;
450 			runtime[2] = 0.0;
451 			runtime[3] = 0.0;
452 			runtime[4] = 0.0;
453 			runtime[5] = 0.0;
454 			runtime[6] = 0.0;
455 			runtime[7] = 0.0;
456 			runtime[8] = 0.0;
457 			runtime[9] = 0.0;
458 			runtime[10] = 0.0;
459 			runtime[11] = (double)((double)(tv[12].tv_sec - tv[1].tv_sec) + (double)((tv[12].tv_usec - tv[1].tv_usec) / 1000.0) / 1000.0);
460 			}
461 		runtime[12] = (double)((double)(tv[13].tv_sec - tv[12].tv_sec) + (double)((tv[13].tv_usec - tv[12].tv_usec) / 1000.0) / 1000.0);
462 		runtime[13] = (double)((double)(tv[13].tv_sec - tv[0].tv_sec) + (double)((tv[13].tv_usec - tv[0].tv_usec) / 1000.0) / 1000.0);
463 
464 		printf("Timing information on object configuration processing is listed\n");
465 		printf("below.  You can use this information to see if precaching your\n");
466 		printf("object configuration would be useful.\n\n");
467 
468 		printf("Object Config Source: %s\n\n", (use_precached_objects == TRUE) ? "Pre-cached config file" : "Config files (uncached)");
469 
470 		printf("OBJECT CONFIG PROCESSING TIMES      (* = Potential for precache savings with -u option)\n");
471 		printf("----------------------------------\n");
472 		printf("Read:                 %.6lf sec\n", runtime[0]);
473 		printf("Resolve:              %.6lf sec  *\n", runtime[1]);
474 		printf("Recomb Contactgroups: %.6lf sec  *\n", runtime[2]);
475 		printf("Recomb Hostgroups:    %.6lf sec  *\n", runtime[3]);
476 		printf("Dup Services:         %.6lf sec  *\n", runtime[4]);
477 		printf("Recomb Servicegroups: %.6lf sec  *\n", runtime[5]);
478 		printf("Duplicate:            %.6lf sec  *\n", runtime[6]);
479 		printf("Inherit:              %.6lf sec  *\n", runtime[7]);
480 		printf("Recomb Contacts:      %.6lf sec  *\n", runtime[8]);
481 		printf("Sort:                 %.6lf sec  *\n", runtime[9]);
482 		/*		printf("Cache:                %.6lf sec\n",runtime[10]);*/
483 		printf("Register:             %.6lf sec\n", runtime[11]);
484 		printf("Free:                 %.6lf sec\n", runtime[12]);
485 		printf("                      ============\n");
486 		printf("TOTAL:                %.6lf sec  ", runtime[13]);
487 		if(use_precached_objects == FALSE)
488 			printf("* = %.6lf sec (%.2f%%) estimated savings", runtime[13] - runtime[12] - runtime[11] - runtime[0], ((runtime[13] - runtime[12] - runtime[11] - runtime[0]) / runtime[13]) * 100.0);
489 		printf("\n");
490 		printf("\n\n");
491 		}
492 #endif
493 
494 	return result;
495 	}
496 
497 
498 
499 /* grab config variable from main config file */
xodtemplate_grab_config_info(char * main_config_file)500 int xodtemplate_grab_config_info(char *main_config_file) {
501 	char *input = NULL;
502 	char *var = NULL;
503 	char *val = NULL;
504 	mmapfile *thefile = NULL;
505 #ifdef NSCORE
506 	nagios_macros *mac;
507 #endif
508 
509 	/* open the main config file for reading */
510 	if((thefile = mmap_fopen(main_config_file)) == NULL)
511 		return ERROR;
512 
513 	/* read in all lines from the main config file */
514 	while(1) {
515 
516 		/* free memory */
517 		my_free(input);
518 
519 		/* read the next line */
520 		if((input = mmap_fgets_multiline(thefile)) == NULL)
521 			break;
522 
523 		/* strip input */
524 		strip(input);
525 
526 		/* skip blank lines and comments */
527 		if(input[0] == '#' || input[0] == ';' || input[0] == '\x0')
528 			continue;
529 
530 		if((var = strtok(input, "=")) == NULL)
531 			continue;
532 
533 		if((val = strtok(NULL, "\n")) == NULL)
534 			continue;
535 
536 		/* cached object file definition (overrides default location) */
537 		if(!strcmp(var, "object_cache_file"))
538 			xodtemplate_cache_file = (char *)strdup(val);
539 
540 		/* pre-cached object file definition */
541 		if(!strcmp(var, "precached_object_file"))
542 			xodtemplate_precache_file = (char *)strdup(val);
543 		}
544 
545 	/* close the file */
546 	mmap_fclose(thefile);
547 
548 	/* default locations */
549 	if(xodtemplate_cache_file == NULL)
550 		xodtemplate_cache_file = (char *)strdup(DEFAULT_OBJECT_CACHE_FILE);
551 	if(xodtemplate_precache_file == NULL)
552 		xodtemplate_precache_file = (char *)strdup(DEFAULT_PRECACHED_OBJECT_FILE);
553 
554 	/* make sure we have what we need */
555 	if(xodtemplate_cache_file == NULL || xodtemplate_precache_file == NULL)
556 		return ERROR;
557 
558 #ifdef NSCORE
559 	mac = get_global_macros();
560 	/* save the object cache file macro */
561 	my_free(mac->x[MACRO_OBJECTCACHEFILE]);
562 	if((mac->x[MACRO_OBJECTCACHEFILE] = (char *)strdup(xodtemplate_cache_file)))
563 		strip(mac->x[MACRO_OBJECTCACHEFILE]);
564 #endif
565 
566 	return OK;
567 	}
568 
569 
570 
571 /* process all files in a specific config directory */
xodtemplate_process_config_dir(char * dirname,int options)572 int xodtemplate_process_config_dir(char *dirname, int options) {
573 	char file[MAX_FILENAME_LENGTH];
574 	DIR *dirp = NULL;
575 	struct dirent *dirfile = NULL;
576 	int result = OK;
577 	register int x = 0;
578 	struct stat stat_buf;
579 
580 #ifdef NSCORE
581 	if(verify_config == TRUE)
582 		printf("Processing object config directory '%s'...\n", dirname);
583 #endif
584 
585 	/* open the directory for reading */
586 	dirp = opendir(dirname);
587 	if(dirp == NULL) {
588 		logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not open config directory '%s' for reading.\n", dirname);
589 		return ERROR;
590 		}
591 
592 	/* process all files in the directory... */
593 	while((dirfile = readdir(dirp)) != NULL) {
594 
595 		/* skip hidden files and directories, and current and parent dir */
596 		if(dirfile->d_name[0] == '.')
597 			continue;
598 
599 		/* create /path/to/file */
600 		snprintf(file, sizeof(file), "%s/%s", dirname, dirfile->d_name);
601 		file[sizeof(file) - 1] = '\x0';
602 
603 		/* process this if it's a non-hidden config file... */
604 		if(stat(file, &stat_buf) == -1) {
605 			logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Could not open config directory member '%s' for reading.\n", file);
606 			closedir(dirp);
607 			return ERROR;
608 			}
609 
610 		switch(stat_buf.st_mode & S_IFMT) {
611 
612 			case S_IFREG:
613 				x = strlen(dirfile->d_name);
614 				if(x <= 4 || strcmp(dirfile->d_name + (x - 4), ".cfg"))
615 					break;
616 
617 				/* process the config file */
618 				result = xodtemplate_process_config_file(file, options);
619 
620 				if(result == ERROR) {
621 					closedir(dirp);
622 					return ERROR;
623 					}
624 
625 				break;
626 
627 			case S_IFDIR:
628 				/* recurse into subdirectories... */
629 				result = xodtemplate_process_config_dir(file, options);
630 
631 				if(result == ERROR) {
632 					closedir(dirp);
633 					return ERROR;
634 					}
635 
636 				break;
637 
638 			default:
639 				/* everything else we ignore */
640 				break;
641 			}
642 		}
643 
644 	closedir(dirp);
645 
646 	return result;
647 	}
648 
649 
650 /* process data in a specific config file */
xodtemplate_process_config_file(char * filename,int options)651 int xodtemplate_process_config_file(char *filename, int options) {
652 	mmapfile *thefile = NULL;
653 	char *input = NULL;
654 	register int in_definition = FALSE;
655 	register int current_line = 0;
656 	int result = OK;
657 	register int x = 0;
658 	register int y = 0;
659 	char *ptr = NULL;
660 
661 
662 #ifdef NSCORE
663 	if(verify_config == TRUE)
664 		printf("Processing object config file '%s'...\n", filename);
665 #endif
666 
667 	/* save config file name */
668 	xodtemplate_config_files[xodtemplate_current_config_file++] = (char *)strdup(filename);
669 
670 	/* reallocate memory for config files */
671 	if(!(xodtemplate_current_config_file % 256)) {
672 		xodtemplate_config_files = (char **)realloc(xodtemplate_config_files, (xodtemplate_current_config_file + 256) * sizeof(char **));
673 		if(xodtemplate_config_files == NULL)
674 			return ERROR;
675 		}
676 
677 	/* open the config file for reading */
678 	if((thefile = mmap_fopen(filename)) == NULL) {
679 		logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Cannot open config file '%s' for reading: %s\n", filename, strerror(errno));
680 		return ERROR;
681 		}
682 
683 	/* read in all lines from the config file */
684 	while(1) {
685 
686 		/* free memory */
687 		my_free(input);
688 
689 		/* read the next line */
690 		if((input = mmap_fgets_multiline(thefile)) == NULL)
691 			break;
692 
693 		current_line = thefile->current_line;
694 
695 		/* grab data before comment delimiter - faster than a strtok() and strncpy()... */
696 		for(x = 0; input[x] != '\x0'; x++) {
697 			if(input[x] == ';') {
698 				if(x == 0)
699 					break;
700 				else if(input[x - 1] != '\\')
701 					break;
702 				}
703 			}
704 		input[x] = '\x0';
705 
706 		/* strip input */
707 		strip(input);
708 
709 		/* skip empty lines */
710 		if(input[0] == '\x0' || input[0] == '#')
711 			continue;
712 
713 		/* this is the start of an object definition */
714 		if(strstr(input, "define") == input) {
715 
716 			/* get the type of object we're defining... */
717 			for(x = 6; input[x] != '\x0'; x++)
718 				if(input[x] != ' ' && input[x] != '\t')
719 					break;
720 			for(y = 0; input[x] != '\x0'; x++) {
721 				if(input[x] == ' ' || input[x] == '\t' ||  input[x] == '{')
722 					break;
723 				else
724 					input[y++] = input[x];
725 				}
726 			input[y] = '\x0';
727 
728 			/* make sure an object type is specified... */
729 			if(input[0] == '\x0') {
730 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: No object type specified in file '%s' on line %d.\n", filename, current_line);
731 				result = ERROR;
732 				break;
733 				}
734 
735 			/* check validity of object type */
736 			if(strcmp(input, "timeperiod") && strcmp(input, "command") && strcmp(input, "contact") && strcmp(input, "contactgroup") && strcmp(input, "host") && strcmp(input, "hostgroup") && strcmp(input, "servicegroup") && strcmp(input, "service") && strcmp(input, "servicedependency") && strcmp(input, "serviceescalation") && strcmp(input, "hostgroupescalation") && strcmp(input, "hostdependency") && strcmp(input, "hostescalation") && strcmp(input, "hostextinfo") && strcmp(input, "serviceextinfo")) {
737 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid object definition type '%s' in file '%s' on line %d.\n", input, filename, current_line);
738 				result = ERROR;
739 				break;
740 				}
741 
742 			/* we're already in an object definition... */
743 			if(in_definition == TRUE) {
744 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Unexpected start of object definition in file '%s' on line %d.  Make sure you close preceding objects before starting a new one.\n", filename, current_line);
745 				result = ERROR;
746 				break;
747 				}
748 
749 			/* start a new definition */
750 			if(xodtemplate_begin_object_definition(input, options, xodtemplate_current_config_file, current_line) == ERROR) {
751 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add object definition in file '%s' on line %d.\n", filename, current_line);
752 				result = ERROR;
753 				break;
754 				}
755 
756 			in_definition = TRUE;
757 			}
758 
759 		/* we're currently inside an object definition */
760 		else if(in_definition == TRUE) {
761 
762 			/* this is the close of an object definition */
763 			if(!strcmp(input, "}")) {
764 
765 				in_definition = FALSE;
766 
767 				/* close out current definition */
768 				if(xodtemplate_end_object_definition(options) == ERROR) {
769 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not complete object definition in file '%s' on line %d.\n", filename, current_line);
770 					result = ERROR;
771 					break;
772 					}
773 				}
774 
775 			/* this is a directive inside an object definition */
776 			else {
777 
778 				/* add directive to object definition */
779 				if(xodtemplate_add_object_property(input, options) == ERROR) {
780 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add object property in file '%s' on line %d.\n", filename, current_line);
781 					result = ERROR;
782 					break;
783 					}
784 				}
785 			}
786 
787 		/* include another file */
788 		else if(strstr(input, "include_file=") == input) {
789 
790 			ptr = strtok(input, "=");
791 			ptr = strtok(NULL, "\n");
792 
793 			if(ptr != NULL) {
794 				result = xodtemplate_process_config_file(ptr, options);
795 				if(result == ERROR)
796 					break;
797 				}
798 			}
799 
800 		/* include a directory */
801 		else if(strstr(input, "include_dir") == input) {
802 
803 			ptr = strtok(input, "=");
804 			ptr = strtok(NULL, "\n");
805 
806 			if(ptr != NULL) {
807 				result = xodtemplate_process_config_dir(ptr, options);
808 				if(result == ERROR)
809 					break;
810 				}
811 			}
812 
813 		/* unexpected token or statement */
814 		else {
815 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Unexpected token or statement in file '%s' on line %d.\n", filename, current_line);
816 			result = ERROR;
817 			break;
818 			}
819 		}
820 
821 	/* free memory and close file */
822 	my_free(input);
823 	mmap_fclose(thefile);
824 
825 	/* whoops - EOF while we were in the middle of an object definition... */
826 	if(in_definition == TRUE && result == OK) {
827 		logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Unexpected EOF in file '%s' on line %d - check for a missing closing bracket.\n", filename, current_line);
828 		result = ERROR;
829 		}
830 
831 	return result;
832 	}
833 
834 
835 
836 
837 
838 /******************************************************************/
839 /***************** OBJECT DEFINITION FUNCTIONS ********************/
840 /******************************************************************/
841 
842 /*
843  * all objects start the same way, so we can get rid of quite
844  * a lot of code with this struct-offset-insensitive macro
845  */
846 #define xod_begin_def(type) \
847 	do { \
848 		new_##type = (xodtemplate_##type *)calloc(1, sizeof(*new_##type)); \
849 		if (new_##type == NULL) \
850 			return ERROR; \
851 		new_##type->register_object=TRUE; \
852 		new_##type->_config_file=config_file; \
853 		new_##type->_start_line=start_line; \
854 	\
855 		/* precached object files are already sorted, so add to tail */ \
856 		if(presorted_objects==TRUE){ \
857 			\
858 			if(xodtemplate_##type##_list==NULL){ \
859 				xodtemplate_##type##_list=new_##type; \
860 				xodtemplate_##type##_list_tail=xodtemplate_##type##_list; \
861 			} else { \
862 				xodtemplate_##type##_list_tail->next=new_##type; \
863 				xodtemplate_##type##_list_tail=new_##type; \
864 			} \
865 	\
866 			/* update current object pointer */ \
867 			xodtemplate_current_object=xodtemplate_##type##_list_tail; \
868 		} else { \
869 			/* add new object to head of list in memory */ \
870 			new_##type->next=xodtemplate_##type##_list; \
871 			xodtemplate_##type##_list=new_##type; \
872 	\
873 			/* update current object pointer */ \
874 			xodtemplate_current_object=xodtemplate_##type##_list; \
875 		} \
876 	} while (0)
877 
878 /* starts a new object definition */
xodtemplate_begin_object_definition(char * input,int options,int config_file,int start_line)879 int xodtemplate_begin_object_definition(char *input, int options, int config_file, int start_line) {
880 	int result = OK;
881 	xodtemplate_timeperiod *new_timeperiod = NULL;
882 	xodtemplate_command *new_command = NULL;
883 	xodtemplate_contactgroup *new_contactgroup = NULL;
884 	xodtemplate_hostgroup *new_hostgroup = NULL;
885 	xodtemplate_servicegroup *new_servicegroup = NULL;
886 	xodtemplate_servicedependency *new_servicedependency = NULL;
887 	xodtemplate_serviceescalation *new_serviceescalation = NULL;
888 	xodtemplate_contact *new_contact = NULL;
889 	xodtemplate_host *new_host = NULL;
890 	xodtemplate_service *new_service = NULL;
891 	xodtemplate_hostdependency *new_hostdependency = NULL;
892 	xodtemplate_hostescalation *new_hostescalation = NULL;
893 	xodtemplate_hostextinfo *new_hostextinfo = NULL;
894 	xodtemplate_serviceextinfo *new_serviceextinfo = NULL;
895 
896 	if(!strcmp(input, "service"))
897 		xodtemplate_current_object_type = XODTEMPLATE_SERVICE;
898 	else if(!strcmp(input, "host"))
899 		xodtemplate_current_object_type = XODTEMPLATE_HOST;
900 	else if(!strcmp(input, "command"))
901 		xodtemplate_current_object_type = XODTEMPLATE_COMMAND;
902 	else if(!strcmp(input, "contact"))
903 		xodtemplate_current_object_type = XODTEMPLATE_CONTACT;
904 	else if(!strcmp(input, "contactgroup"))
905 		xodtemplate_current_object_type = XODTEMPLATE_CONTACTGROUP;
906 	else if(!strcmp(input, "hostgroup"))
907 		xodtemplate_current_object_type = XODTEMPLATE_HOSTGROUP;
908 	else if(!strcmp(input, "servicegroup"))
909 		xodtemplate_current_object_type = XODTEMPLATE_SERVICEGROUP;
910 	else if(!strcmp(input, "timeperiod"))
911 		xodtemplate_current_object_type = XODTEMPLATE_TIMEPERIOD;
912 	else if(!strcmp(input, "servicedependency"))
913 		xodtemplate_current_object_type = XODTEMPLATE_SERVICEDEPENDENCY;
914 	else if(!strcmp(input, "serviceescalation"))
915 		xodtemplate_current_object_type = XODTEMPLATE_SERVICEESCALATION;
916 	else if(!strcmp(input, "hostdependency"))
917 		xodtemplate_current_object_type = XODTEMPLATE_HOSTDEPENDENCY;
918 	else if(!strcmp(input, "hostescalation"))
919 		xodtemplate_current_object_type = XODTEMPLATE_HOSTESCALATION;
920 	else if(!strcmp(input, "hostextinfo"))
921 		xodtemplate_current_object_type = XODTEMPLATE_HOSTEXTINFO;
922 	else if(!strcmp(input, "serviceextinfo"))
923 		xodtemplate_current_object_type = XODTEMPLATE_SERVICEEXTINFO;
924 	else
925 		return ERROR;
926 
927 
928 	/* check to see if we should process this type of object */
929 	switch(xodtemplate_current_object_type) {
930 		case XODTEMPLATE_TIMEPERIOD:
931 			if(!(options & READ_TIMEPERIODS))
932 				return OK;
933 			break;
934 		case XODTEMPLATE_COMMAND:
935 			if(!(options & READ_COMMANDS))
936 				return OK;
937 			break;
938 		case XODTEMPLATE_CONTACT:
939 			if(!(options & READ_CONTACTS))
940 				return OK;
941 			break;
942 		case XODTEMPLATE_CONTACTGROUP:
943 			if(!(options & READ_CONTACTGROUPS))
944 				return OK;
945 			break;
946 		case XODTEMPLATE_HOST:
947 			if(!(options & READ_HOSTS))
948 				return OK;
949 			break;
950 		case XODTEMPLATE_HOSTGROUP:
951 			if(!(options & READ_HOSTGROUPS))
952 				return OK;
953 			break;
954 		case XODTEMPLATE_SERVICEGROUP:
955 			if(!(options & READ_SERVICEGROUPS))
956 				return OK;
957 			break;
958 		case XODTEMPLATE_SERVICE:
959 			if(!(options & READ_SERVICES))
960 				return OK;
961 			break;
962 		case XODTEMPLATE_SERVICEDEPENDENCY:
963 			if(!(options & READ_SERVICEDEPENDENCIES))
964 				return OK;
965 			break;
966 		case XODTEMPLATE_SERVICEESCALATION:
967 			if(!(options & READ_SERVICEESCALATIONS))
968 				return OK;
969 			break;
970 		case XODTEMPLATE_HOSTDEPENDENCY:
971 			if(!(options & READ_HOSTDEPENDENCIES))
972 				return OK;
973 			break;
974 		case XODTEMPLATE_HOSTESCALATION:
975 			if(!(options & READ_HOSTESCALATIONS))
976 				return OK;
977 			break;
978 		case XODTEMPLATE_HOSTEXTINFO:
979 			if(!(options & READ_HOSTEXTINFO))
980 				return OK;
981 			break;
982 		case XODTEMPLATE_SERVICEEXTINFO:
983 			if(!(options & READ_SERVICEEXTINFO))
984 				return OK;
985 			break;
986 		default:
987 			return ERROR;
988 			break;
989 		}
990 
991 
992 
993 	/* add a new (blank) object */
994 	switch(xodtemplate_current_object_type) {
995 
996 		case XODTEMPLATE_TIMEPERIOD:
997 			xod_begin_def(timeperiod);
998 			break;
999 
1000 		case XODTEMPLATE_COMMAND:
1001 			xod_begin_def(command);
1002 			break;
1003 
1004 		case XODTEMPLATE_CONTACTGROUP:
1005 			xod_begin_def(contactgroup);
1006 			break;
1007 
1008 		case XODTEMPLATE_HOSTGROUP:
1009 			xod_begin_def(hostgroup);
1010 			break;
1011 
1012 		case XODTEMPLATE_SERVICEGROUP:
1013 			xod_begin_def(servicegroup);
1014 			break;
1015 
1016 		case XODTEMPLATE_SERVICEDEPENDENCY:
1017 			xod_begin_def(servicedependency);
1018 			break;
1019 
1020 		case XODTEMPLATE_SERVICEESCALATION:
1021 			xod_begin_def(serviceescalation);
1022 			new_serviceescalation->first_notification = -2;
1023 			new_serviceescalation->last_notification = -2;
1024 			break;
1025 
1026 		case XODTEMPLATE_CONTACT:
1027 			xod_begin_def(contact);
1028 
1029 			new_contact->host_notifications_enabled = TRUE;
1030 			new_contact->service_notifications_enabled = TRUE;
1031 			new_contact->can_submit_commands = TRUE;
1032 			new_contact->retain_status_information = TRUE;
1033 			new_contact->retain_nonstatus_information = TRUE;
1034 			break;
1035 
1036 		case XODTEMPLATE_HOST:
1037 			xod_begin_def(host);
1038 			new_host->check_interval = 5.0;
1039 			new_host->retry_interval = 1.0;
1040 			new_host->active_checks_enabled = TRUE;
1041 			new_host->passive_checks_enabled = TRUE;
1042 			new_host->obsess_over_host = TRUE;
1043 			new_host->max_check_attempts = -2;
1044 			new_host->event_handler_enabled = TRUE;
1045 			new_host->flap_detection_enabled = TRUE;
1046 			new_host->flap_detection_on_up = TRUE;
1047 			new_host->flap_detection_on_down = TRUE;
1048 			new_host->flap_detection_on_unreachable = TRUE;
1049 			new_host->notifications_enabled = TRUE;
1050 			new_host->notification_interval = 30.0;
1051 			new_host->process_perf_data = TRUE;
1052 			new_host->failure_prediction_enabled = TRUE;
1053 			new_host->x_2d = -1;
1054 			new_host->y_2d = -1;
1055 			new_host->retain_status_information = TRUE;
1056 			new_host->retain_nonstatus_information = TRUE;
1057 			break;
1058 
1059 		case XODTEMPLATE_SERVICE:
1060 			xod_begin_def(service);
1061 
1062 			new_service->initial_state = STATE_OK;
1063 			new_service->max_check_attempts = -2;
1064 			new_service->check_interval = 5.0;
1065 			new_service->retry_interval = 1.0;
1066 			new_service->active_checks_enabled = TRUE;
1067 			new_service->passive_checks_enabled = TRUE;
1068 			new_service->parallelize_check = TRUE;
1069 			new_service->obsess_over_service = TRUE;
1070 			new_service->event_handler_enabled = TRUE;
1071 			new_service->flap_detection_enabled = TRUE;
1072 			new_service->flap_detection_on_ok = TRUE;
1073 			new_service->flap_detection_on_warning = TRUE;
1074 			new_service->flap_detection_on_unknown = TRUE;
1075 			new_service->flap_detection_on_critical = TRUE;
1076 			new_service->notifications_enabled = TRUE;
1077 			new_service->notification_interval = 30.0;
1078 			new_service->process_perf_data = TRUE;
1079 			new_service->failure_prediction_enabled = TRUE;
1080 			new_service->retain_status_information = TRUE;
1081 			new_service->retain_nonstatus_information = TRUE;
1082 
1083 			/* true service, so is not from host group, must be set AFTER have_initial_state*/
1084 			xodtemplate_unset_service_is_from_hostgroup(new_service);
1085 			break;
1086 
1087 		case XODTEMPLATE_HOSTDEPENDENCY:
1088 			xod_begin_def(hostdependency);
1089 			break;
1090 
1091 		case XODTEMPLATE_HOSTESCALATION:
1092 			xod_begin_def(hostescalation);
1093 			new_hostescalation->first_notification = -2;
1094 			new_hostescalation->last_notification = -2;
1095 			break;
1096 
1097 		case XODTEMPLATE_HOSTEXTINFO:
1098 			xod_begin_def(hostextinfo);
1099 
1100 			new_hostextinfo->x_2d = -1;
1101 			new_hostextinfo->y_2d = -1;
1102 			break;
1103 
1104 		case XODTEMPLATE_SERVICEEXTINFO:
1105 			xod_begin_def(serviceextinfo);
1106 			break;
1107 
1108 		default:
1109 			return ERROR;
1110 			break;
1111 		}
1112 
1113 	return result;
1114 	}
1115 #undef xod_begin_def /* we don't need this anymore */
1116 
1117 
1118 /* adds a property to an object definition */
xodtemplate_add_object_property(char * input,int options)1119 int xodtemplate_add_object_property(char *input, int options) {
1120 	int result = OK;
1121 	char *variable = NULL;
1122 	char *value = NULL;
1123 	char *temp_ptr = NULL;
1124 	char *customvarname = NULL;
1125 	char *customvarvalue = NULL;
1126 	xodtemplate_timeperiod *temp_timeperiod = NULL;
1127 	xodtemplate_command *temp_command = NULL;
1128 	xodtemplate_contactgroup *temp_contactgroup = NULL;
1129 	xodtemplate_hostgroup *temp_hostgroup = NULL;
1130 	xodtemplate_servicegroup *temp_servicegroup = NULL;
1131 	xodtemplate_servicedependency *temp_servicedependency = NULL;
1132 	xodtemplate_serviceescalation *temp_serviceescalation = NULL;
1133 	xodtemplate_contact *temp_contact = NULL;
1134 	xodtemplate_host *temp_host = NULL;
1135 	xodtemplate_service *temp_service = NULL;
1136 	xodtemplate_hostdependency *temp_hostdependency = NULL;
1137 	xodtemplate_hostescalation *temp_hostescalation = NULL;
1138 	xodtemplate_hostextinfo *temp_hostextinfo = NULL;
1139 	xodtemplate_serviceextinfo *temp_serviceextinfo = NULL;
1140 	register int x = 0;
1141 	register int y = 0;
1142 	int force_skiplists = FALSE;
1143 
1144 
1145 	/* should some object definitions be added to skiplists immediately? */
1146 #ifdef NSCORE
1147 	if(use_precached_objects == TRUE)
1148 		force_skiplists = TRUE;
1149 #else
1150 	force_skiplists = TRUE;
1151 #endif
1152 
1153 	/* check to see if we should process this type of object */
1154 	switch(xodtemplate_current_object_type) {
1155 		case XODTEMPLATE_TIMEPERIOD:
1156 			if(!(options & READ_TIMEPERIODS))
1157 				return OK;
1158 			break;
1159 		case XODTEMPLATE_COMMAND:
1160 			if(!(options & READ_COMMANDS))
1161 				return OK;
1162 			break;
1163 		case XODTEMPLATE_CONTACT:
1164 			if(!(options & READ_CONTACTS))
1165 				return OK;
1166 			break;
1167 		case XODTEMPLATE_CONTACTGROUP:
1168 			if(!(options & READ_CONTACTGROUPS))
1169 				return OK;
1170 			break;
1171 		case XODTEMPLATE_HOST:
1172 			if(!(options & READ_HOSTS))
1173 				return OK;
1174 			break;
1175 		case XODTEMPLATE_HOSTGROUP:
1176 			if(!(options & READ_HOSTGROUPS))
1177 				return OK;
1178 			break;
1179 		case XODTEMPLATE_SERVICEGROUP:
1180 			if(!(options & READ_SERVICEGROUPS))
1181 				return OK;
1182 			break;
1183 		case XODTEMPLATE_SERVICE:
1184 			if(!(options & READ_SERVICES))
1185 				return OK;
1186 			break;
1187 		case XODTEMPLATE_SERVICEDEPENDENCY:
1188 			if(!(options & READ_SERVICEDEPENDENCIES))
1189 				return OK;
1190 			break;
1191 		case XODTEMPLATE_SERVICEESCALATION:
1192 			if(!(options & READ_SERVICEESCALATIONS))
1193 				return OK;
1194 			break;
1195 		case XODTEMPLATE_HOSTDEPENDENCY:
1196 			if(!(options & READ_HOSTDEPENDENCIES))
1197 				return OK;
1198 			break;
1199 		case XODTEMPLATE_HOSTESCALATION:
1200 			if(!(options & READ_HOSTESCALATIONS))
1201 				return OK;
1202 			break;
1203 		case XODTEMPLATE_HOSTEXTINFO:
1204 			if(!(options & READ_HOSTEXTINFO))
1205 				return OK;
1206 			break;
1207 		case XODTEMPLATE_SERVICEEXTINFO:
1208 			if(!(options & READ_SERVICEEXTINFO))
1209 				return OK;
1210 			break;
1211 		default:
1212 			return ERROR;
1213 			break;
1214 		}
1215 
1216 	/* get variable name */
1217 	if((variable = (char *)strdup(input)) == NULL)
1218 		return ERROR;
1219 	/* trim at first whitespace occurance */
1220 	for(x = 0, y = 0; variable[x] != '\x0'; x++) {
1221 		if(variable[x] == ' ' || variable[x] == '\t')
1222 			break;
1223 		y++;
1224 		}
1225 	variable[y] = '\x0';
1226 
1227 	/* get variable value */
1228 	if((value = (char *)strdup(input + x)) == NULL) {
1229 		my_free(variable);
1230 		return ERROR;
1231 		}
1232 	strip(value);
1233 
1234 
1235 	switch(xodtemplate_current_object_type) {
1236 
1237 		case XODTEMPLATE_TIMEPERIOD:
1238 
1239 			temp_timeperiod = (xodtemplate_timeperiod *)xodtemplate_current_object;
1240 
1241 			if(!strcmp(variable, "use")) {
1242 				if((temp_timeperiod->template = (char *)strdup(value)) == NULL)
1243 					result = ERROR;
1244 				}
1245 			else if(!strcmp(variable, "name")) {
1246 
1247 				if((temp_timeperiod->name = (char *)strdup(value)) == NULL)
1248 					result = ERROR;
1249 
1250 				if(result == OK) {
1251 					/* add timeperiod to template skiplist for fast searches */
1252 					result = skiplist_insert(xobject_template_skiplists[X_TIMEPERIOD_SKIPLIST], (void *)temp_timeperiod);
1253 					switch(result) {
1254 						case SKIPLIST_ERROR_DUPLICATE:
1255 							logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for timeperiod '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_timeperiod->_config_file), temp_timeperiod->_start_line);
1256 							result = ERROR;
1257 							break;
1258 						case SKIPLIST_OK:
1259 							result = OK;
1260 							break;
1261 						default:
1262 							result = ERROR;
1263 							break;
1264 						}
1265 					}
1266 				}
1267 			else if(!strcmp(variable, "timeperiod_name")) {
1268 				if((temp_timeperiod->timeperiod_name = (char *)strdup(value)) == NULL)
1269 					result = ERROR;
1270 
1271 				if(result == OK) {
1272 					/* add timeperiod to template skiplist for fast searches */
1273 					result = skiplist_insert(xobject_skiplists[X_TIMEPERIOD_SKIPLIST], (void *)temp_timeperiod);
1274 					switch(result) {
1275 						case SKIPLIST_ERROR_DUPLICATE:
1276 							logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for timeperiod '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_timeperiod->_config_file), temp_timeperiod->_start_line);
1277 							result = ERROR;
1278 							break;
1279 						case SKIPLIST_OK:
1280 							result = OK;
1281 							break;
1282 						default:
1283 							result = ERROR;
1284 							break;
1285 						}
1286 					}
1287 				}
1288 			else if(!strcmp(variable, "alias")) {
1289 				if((temp_timeperiod->alias = (char *)strdup(value)) == NULL)
1290 					result = ERROR;
1291 				}
1292 			else if(!strcmp(variable, "exclude")) {
1293 				if((temp_timeperiod->exclusions = (char *)strdup(value)) == NULL)
1294 					result = ERROR;
1295 				}
1296 			else if(!strcmp(variable, "register"))
1297 				temp_timeperiod->register_object = (atoi(value) > 0) ? TRUE : FALSE;
1298 			else if(xodtemplate_parse_timeperiod_directive(temp_timeperiod, variable, value) == OK)
1299 				result = OK;
1300 			else {
1301 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid timeperiod object directive '%s'.\n", variable);
1302 				return ERROR;
1303 				}
1304 			break;
1305 
1306 
1307 
1308 		case XODTEMPLATE_COMMAND:
1309 
1310 			temp_command = (xodtemplate_command *)xodtemplate_current_object;
1311 
1312 			if(!strcmp(variable, "use")) {
1313 				if((temp_command->template = (char *)strdup(value)) == NULL)
1314 					result = ERROR;
1315 				}
1316 			else if(!strcmp(variable, "name")) {
1317 
1318 				if((temp_command->name = (char *)strdup(value)) == NULL)
1319 					result = ERROR;
1320 
1321 				if(result == OK) {
1322 					/* add command to template skiplist for fast searches */
1323 					result = skiplist_insert(xobject_template_skiplists[X_COMMAND_SKIPLIST], (void *)temp_command);
1324 					switch(result) {
1325 						case SKIPLIST_ERROR_DUPLICATE:
1326 							logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for command '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_command->_config_file), temp_command->_start_line);
1327 							result = ERROR;
1328 							break;
1329 						case SKIPLIST_OK:
1330 							result = OK;
1331 							break;
1332 						default:
1333 							result = ERROR;
1334 							break;
1335 						}
1336 					}
1337 				}
1338 			else if(!strcmp(variable, "command_name")) {
1339 				if((temp_command->command_name = (char *)strdup(value)) == NULL)
1340 					result = ERROR;
1341 
1342 				if(result == OK) {
1343 					/* add command to template skiplist for fast searches */
1344 					result = skiplist_insert(xobject_skiplists[X_COMMAND_SKIPLIST], (void *)temp_command);
1345 					switch(result) {
1346 						case SKIPLIST_ERROR_DUPLICATE:
1347 							logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for command '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_command->_config_file), temp_command->_start_line);
1348 							result = ERROR;
1349 							break;
1350 						case SKIPLIST_OK:
1351 							result = OK;
1352 							break;
1353 						default:
1354 							result = ERROR;
1355 							break;
1356 						}
1357 					}
1358 				}
1359 			else if(!strcmp(variable, "command_line")) {
1360 				if((temp_command->command_line = (char *)strdup(value)) == NULL)
1361 					result = ERROR;
1362 				}
1363 			else if(!strcmp(variable, "register"))
1364 				temp_command->register_object = (atoi(value) > 0) ? TRUE : FALSE;
1365 			else {
1366 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid command object directive '%s'.\n", variable);
1367 				return ERROR;
1368 				}
1369 
1370 			break;
1371 
1372 		case XODTEMPLATE_CONTACTGROUP:
1373 
1374 			temp_contactgroup = (xodtemplate_contactgroup *)xodtemplate_current_object;
1375 
1376 			if(!strcmp(variable, "use")) {
1377 				if((temp_contactgroup->template = (char *)strdup(value)) == NULL)
1378 					result = ERROR;
1379 				}
1380 			else if(!strcmp(variable, "name")) {
1381 
1382 				if((temp_contactgroup->name = (char *)strdup(value)) == NULL)
1383 					result = ERROR;
1384 
1385 				if(result == OK) {
1386 					/* add contactgroup to template skiplist for fast searches */
1387 					result = skiplist_insert(xobject_template_skiplists[X_CONTACTGROUP_SKIPLIST], (void *)temp_contactgroup);
1388 					switch(result) {
1389 						case SKIPLIST_ERROR_DUPLICATE:
1390 							logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for contactgroup '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_contactgroup->_config_file), temp_contactgroup->_start_line);
1391 							result = ERROR;
1392 							break;
1393 						case SKIPLIST_OK:
1394 							result = OK;
1395 							break;
1396 						default:
1397 							result = ERROR;
1398 							break;
1399 						}
1400 					}
1401 				}
1402 			else if(!strcmp(variable, "contactgroup_name")) {
1403 				if((temp_contactgroup->contactgroup_name = (char *)strdup(value)) == NULL)
1404 					result = ERROR;
1405 
1406 				if(result == OK) {
1407 					/* add contactgroup to template skiplist for fast searches */
1408 					result = skiplist_insert(xobject_skiplists[X_CONTACTGROUP_SKIPLIST], (void *)temp_contactgroup);
1409 					switch(result) {
1410 						case SKIPLIST_ERROR_DUPLICATE:
1411 							logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for contactgroup '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_contactgroup->_config_file), temp_contactgroup->_start_line);
1412 							result = ERROR;
1413 							break;
1414 						case SKIPLIST_OK:
1415 							result = OK;
1416 							break;
1417 						default:
1418 							result = ERROR;
1419 							break;
1420 						}
1421 					}
1422 				}
1423 			else if(!strcmp(variable, "alias")) {
1424 				if((temp_contactgroup->alias = (char *)strdup(value)) == NULL)
1425 					result = ERROR;
1426 				}
1427 			else if(!strcmp(variable, "members")) {
1428 				if(strcmp(value, XODTEMPLATE_NULL)) {
1429 					if(temp_contactgroup->members == NULL)
1430 						temp_contactgroup->members = (char *)strdup(value);
1431 					else {
1432 						temp_contactgroup->members = (char *)realloc(temp_contactgroup->members, strlen(temp_contactgroup->members) + strlen(value) + 2);
1433 						if(temp_contactgroup->members != NULL) {
1434 							strcat(temp_contactgroup->members, ",");
1435 							strcat(temp_contactgroup->members, value);
1436 							}
1437 						}
1438 					if(temp_contactgroup->members == NULL)
1439 						result = ERROR;
1440 					}
1441 				temp_contactgroup->have_members = TRUE;
1442 				}
1443 			else if(!strcmp(variable, "contactgroup_members")) {
1444 				if(strcmp(value, XODTEMPLATE_NULL)) {
1445 					if(temp_contactgroup->contactgroup_members == NULL)
1446 						temp_contactgroup->contactgroup_members = (char *)strdup(value);
1447 					else {
1448 						temp_contactgroup->contactgroup_members = (char *)realloc(temp_contactgroup->contactgroup_members, strlen(temp_contactgroup->contactgroup_members) + strlen(value) + 2);
1449 						if(temp_contactgroup->contactgroup_members != NULL) {
1450 							strcat(temp_contactgroup->contactgroup_members, ",");
1451 							strcat(temp_contactgroup->contactgroup_members, value);
1452 							}
1453 						}
1454 					if(temp_contactgroup->contactgroup_members == NULL)
1455 						result = ERROR;
1456 					}
1457 				temp_contactgroup->have_contactgroup_members = TRUE;
1458 				}
1459 			else if(!strcmp(variable, "register"))
1460 				temp_contactgroup->register_object = (atoi(value) > 0) ? TRUE : FALSE;
1461 			else {
1462 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid contactgroup object directive '%s'.\n", variable);
1463 				return ERROR;
1464 				}
1465 
1466 			break;
1467 
1468 		case XODTEMPLATE_HOSTGROUP:
1469 
1470 			temp_hostgroup = (xodtemplate_hostgroup *)xodtemplate_current_object;
1471 
1472 			if(!strcmp(variable, "use")) {
1473 				if((temp_hostgroup->template = (char *)strdup(value)) == NULL)
1474 					result = ERROR;
1475 				}
1476 			else if(!strcmp(variable, "name")) {
1477 
1478 				if((temp_hostgroup->name = (char *)strdup(value)) == NULL)
1479 					result = ERROR;
1480 
1481 				if(result == OK) {
1482 					/* add hostgroup to template skiplist for fast searches */
1483 					result = skiplist_insert(xobject_template_skiplists[X_HOSTGROUP_SKIPLIST], (void *)temp_hostgroup);
1484 					switch(result) {
1485 						case SKIPLIST_ERROR_DUPLICATE:
1486 							logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for hostgroup '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_hostgroup->_config_file), temp_hostgroup->_start_line);
1487 							result = ERROR;
1488 							break;
1489 						case SKIPLIST_OK:
1490 							result = OK;
1491 							break;
1492 						default:
1493 							result = ERROR;
1494 							break;
1495 						}
1496 					}
1497 				}
1498 			else if(!strcmp(variable, "hostgroup_name")) {
1499 				if((temp_hostgroup->hostgroup_name = (char *)strdup(value)) == NULL)
1500 					result = ERROR;
1501 
1502 				if(result == OK) {
1503 					/* add hostgroup to template skiplist for fast searches */
1504 					result = skiplist_insert(xobject_skiplists[X_HOSTGROUP_SKIPLIST], (void *)temp_hostgroup);
1505 					switch(result) {
1506 						case SKIPLIST_ERROR_DUPLICATE:
1507 							logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for hostgroup '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_hostgroup->_config_file), temp_hostgroup->_start_line);
1508 							result = ERROR;
1509 							break;
1510 						case SKIPLIST_OK:
1511 							result = OK;
1512 							break;
1513 						default:
1514 							result = ERROR;
1515 							break;
1516 						}
1517 					}
1518 				}
1519 			else if(!strcmp(variable, "alias")) {
1520 				if((temp_hostgroup->alias = (char *)strdup(value)) == NULL)
1521 					result = ERROR;
1522 				}
1523 			else if(!strcmp(variable, "members")) {
1524 				if(strcmp(value, XODTEMPLATE_NULL)) {
1525 					if(temp_hostgroup->members == NULL)
1526 						temp_hostgroup->members = (char *)strdup(value);
1527 					else {
1528 						temp_hostgroup->members = (char *)realloc(temp_hostgroup->members, strlen(temp_hostgroup->members) + strlen(value) + 2);
1529 						if(temp_hostgroup->members != NULL) {
1530 							strcat(temp_hostgroup->members, ",");
1531 							strcat(temp_hostgroup->members, value);
1532 							}
1533 						}
1534 					if(temp_hostgroup->members == NULL)
1535 						result = ERROR;
1536 					}
1537 				temp_hostgroup->have_members = TRUE;
1538 				}
1539 			else if(!strcmp(variable, "hostgroup_members")) {
1540 				if(strcmp(value, XODTEMPLATE_NULL)) {
1541 					if(temp_hostgroup->hostgroup_members == NULL)
1542 						temp_hostgroup->hostgroup_members = (char *)strdup(value);
1543 					else {
1544 						temp_hostgroup->hostgroup_members = (char *)realloc(temp_hostgroup->hostgroup_members, strlen(temp_hostgroup->hostgroup_members) + strlen(value) + 2);
1545 						if(temp_hostgroup->hostgroup_members != NULL) {
1546 							strcat(temp_hostgroup->hostgroup_members, ",");
1547 							strcat(temp_hostgroup->hostgroup_members, value);
1548 							}
1549 						}
1550 					if(temp_hostgroup->hostgroup_members == NULL)
1551 						result = ERROR;
1552 					}
1553 				temp_hostgroup->have_hostgroup_members = TRUE;
1554 				}
1555 			else if(!strcmp(variable, "notes")) {
1556 				if(strcmp(value, XODTEMPLATE_NULL)) {
1557 					if((temp_hostgroup->notes = (char *)strdup(value)) == NULL)
1558 						result = ERROR;
1559 					}
1560 				temp_hostgroup->have_notes = TRUE;
1561 				}
1562 			else if(!strcmp(variable, "notes_url")) {
1563 				if(strcmp(value, XODTEMPLATE_NULL)) {
1564 					if((temp_hostgroup->notes_url = (char *)strdup(value)) == NULL)
1565 						result = ERROR;
1566 					}
1567 				temp_hostgroup->have_notes_url = TRUE;
1568 				}
1569 			else if(!strcmp(variable, "action_url")) {
1570 				if(strcmp(value, XODTEMPLATE_NULL)) {
1571 					if((temp_hostgroup->action_url = (char *)strdup(value)) == NULL)
1572 						result = ERROR;
1573 					}
1574 				temp_hostgroup->have_action_url = TRUE;
1575 				}
1576 			else if(!strcmp(variable, "register"))
1577 				temp_hostgroup->register_object = (atoi(value) > 0) ? TRUE : FALSE;
1578 			else {
1579 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid hostgroup object directive '%s'.\n", variable);
1580 				return ERROR;
1581 				}
1582 
1583 			break;
1584 
1585 
1586 		case XODTEMPLATE_SERVICEGROUP:
1587 
1588 			temp_servicegroup = (xodtemplate_servicegroup *)xodtemplate_current_object;
1589 
1590 			if(!strcmp(variable, "use")) {
1591 				if((temp_servicegroup->template = (char *)strdup(value)) == NULL)
1592 					result = ERROR;
1593 				}
1594 			else if(!strcmp(variable, "name")) {
1595 
1596 				if((temp_servicegroup->name = (char *)strdup(value)) == NULL)
1597 					result = ERROR;
1598 
1599 				if(result == OK) {
1600 					/* add servicegroup to template skiplist for fast searches */
1601 					result = skiplist_insert(xobject_template_skiplists[X_SERVICEGROUP_SKIPLIST], (void *)temp_servicegroup);
1602 					switch(result) {
1603 						case SKIPLIST_ERROR_DUPLICATE:
1604 							logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for servicegroup '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_servicegroup->_config_file), temp_servicegroup->_start_line);
1605 							result = ERROR;
1606 							break;
1607 						case SKIPLIST_OK:
1608 							result = OK;
1609 							break;
1610 						default:
1611 							result = ERROR;
1612 							break;
1613 						}
1614 					}
1615 				}
1616 			else if(!strcmp(variable, "servicegroup_name")) {
1617 				if((temp_servicegroup->servicegroup_name = (char *)strdup(value)) == NULL)
1618 					result = ERROR;
1619 
1620 				if(result == OK) {
1621 					/* add servicegroup to template skiplist for fast searches */
1622 					result = skiplist_insert(xobject_skiplists[X_SERVICEGROUP_SKIPLIST], (void *)temp_servicegroup);
1623 					switch(result) {
1624 						case SKIPLIST_ERROR_DUPLICATE:
1625 							logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for servicegroup '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_servicegroup->_config_file), temp_servicegroup->_start_line);
1626 							result = ERROR;
1627 							break;
1628 						case SKIPLIST_OK:
1629 							result = OK;
1630 							break;
1631 						default:
1632 							result = ERROR;
1633 							break;
1634 						}
1635 					}
1636 				}
1637 			else if(!strcmp(variable, "alias")) {
1638 				if((temp_servicegroup->alias = (char *)strdup(value)) == NULL)
1639 					result = ERROR;
1640 				}
1641 			else if(!strcmp(variable, "members")) {
1642 				if(strcmp(value, XODTEMPLATE_NULL)) {
1643 					if(temp_servicegroup->members == NULL)
1644 						temp_servicegroup->members = (char *)strdup(value);
1645 					else {
1646 						temp_servicegroup->members = (char *)realloc(temp_servicegroup->members, strlen(temp_servicegroup->members) + strlen(value) + 2);
1647 						if(temp_servicegroup->members != NULL) {
1648 							strcat(temp_servicegroup->members, ",");
1649 							strcat(temp_servicegroup->members, value);
1650 							}
1651 						}
1652 					if(temp_servicegroup->members == NULL)
1653 						result = ERROR;
1654 					}
1655 				temp_servicegroup->have_members = TRUE;
1656 				}
1657 			else if(!strcmp(variable, "servicegroup_members")) {
1658 				if(strcmp(value, XODTEMPLATE_NULL)) {
1659 					if(temp_servicegroup->servicegroup_members == NULL)
1660 						temp_servicegroup->servicegroup_members = (char *)strdup(value);
1661 					else {
1662 						temp_servicegroup->servicegroup_members = (char *)realloc(temp_servicegroup->servicegroup_members, strlen(temp_servicegroup->servicegroup_members) + strlen(value) + 2);
1663 						if(temp_servicegroup->servicegroup_members != NULL) {
1664 							strcat(temp_servicegroup->servicegroup_members, ",");
1665 							strcat(temp_servicegroup->servicegroup_members, value);
1666 							}
1667 						}
1668 					if(temp_servicegroup->servicegroup_members == NULL)
1669 						result = ERROR;
1670 					}
1671 				temp_servicegroup->have_servicegroup_members = TRUE;
1672 				}
1673 			else if(!strcmp(variable, "notes")) {
1674 				if(strcmp(value, XODTEMPLATE_NULL)) {
1675 					if((temp_servicegroup->notes = (char *)strdup(value)) == NULL)
1676 						result = ERROR;
1677 					}
1678 				temp_servicegroup->have_notes = TRUE;
1679 				}
1680 			else if(!strcmp(variable, "notes_url")) {
1681 				if(strcmp(value, XODTEMPLATE_NULL)) {
1682 					if((temp_servicegroup->notes_url = (char *)strdup(value)) == NULL)
1683 						result = ERROR;
1684 					}
1685 				temp_servicegroup->have_notes_url = TRUE;
1686 				}
1687 			else if(!strcmp(variable, "action_url")) {
1688 				if(strcmp(value, XODTEMPLATE_NULL)) {
1689 					if((temp_servicegroup->action_url = (char *)strdup(value)) == NULL)
1690 						result = ERROR;
1691 					}
1692 				temp_servicegroup->have_action_url = TRUE;
1693 				}
1694 			else if(!strcmp(variable, "register"))
1695 				temp_servicegroup->register_object = (atoi(value) > 0) ? TRUE : FALSE;
1696 			else {
1697 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid servicegroup object directive '%s'.\n", variable);
1698 				return ERROR;
1699 				}
1700 
1701 			break;
1702 
1703 
1704 		case XODTEMPLATE_SERVICEDEPENDENCY:
1705 
1706 			temp_servicedependency = (xodtemplate_servicedependency *)xodtemplate_current_object;
1707 
1708 			if(!strcmp(variable, "use")) {
1709 				if((temp_servicedependency->template = (char *)strdup(value)) == NULL)
1710 					result = ERROR;
1711 				}
1712 			else if(!strcmp(variable, "name")) {
1713 
1714 				if((temp_servicedependency->name = (char *)strdup(value)) == NULL)
1715 					result = ERROR;
1716 
1717 				if(result == OK) {
1718 					/* add dependency to template skiplist for fast searches */
1719 					result = skiplist_insert(xobject_template_skiplists[X_SERVICEDEPENDENCY_SKIPLIST], (void *)temp_servicedependency);
1720 					switch(result) {
1721 						case SKIPLIST_ERROR_DUPLICATE:
1722 							logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for service dependency '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_servicedependency->_config_file), temp_servicedependency->_start_line);
1723 							result = ERROR;
1724 							break;
1725 						case SKIPLIST_OK:
1726 							result = OK;
1727 							break;
1728 						default:
1729 							result = ERROR;
1730 							break;
1731 						}
1732 					}
1733 				}
1734 			else if(!strcmp(variable, "servicegroup") || !strcmp(variable, "servicegroups") || !strcmp(variable, "servicegroup_name")) {
1735 				if(strcmp(value, XODTEMPLATE_NULL)) {
1736 					if((temp_servicedependency->servicegroup_name = (char *)strdup(value)) == NULL)
1737 						result = ERROR;
1738 					}
1739 				temp_servicedependency->have_servicegroup_name = TRUE;
1740 				}
1741 			else if(!strcmp(variable, "hostgroup") || !strcmp(variable, "hostgroups") || !strcmp(variable, "hostgroup_name")) {
1742 				if(strcmp(value, XODTEMPLATE_NULL)) {
1743 					if((temp_servicedependency->hostgroup_name = (char *)strdup(value)) == NULL)
1744 						result = ERROR;
1745 					}
1746 				temp_servicedependency->have_hostgroup_name = TRUE;
1747 				}
1748 			else if(!strcmp(variable, "host") || !strcmp(variable, "host_name") || !strcmp(variable, "master_host") || !strcmp(variable, "master_host_name")) {
1749 				if(strcmp(value, XODTEMPLATE_NULL)) {
1750 					if((temp_servicedependency->host_name = (char *)strdup(value)) == NULL)
1751 						result = ERROR;
1752 					}
1753 				temp_servicedependency->have_host_name = TRUE;
1754 				}
1755 			else if(!strcmp(variable, "description") || !strcmp(variable, "service_description") || !strcmp(variable, "master_description") || !strcmp(variable, "master_service_description")) {
1756 				if(strcmp(value, XODTEMPLATE_NULL)) {
1757 					if((temp_servicedependency->service_description = (char *)strdup(value)) == NULL)
1758 						result = ERROR;
1759 					}
1760 				temp_servicedependency->have_service_description = TRUE;
1761 				}
1762 			else if(!strcmp(variable, "dependent_servicegroup") || !strcmp(variable, "dependent_servicegroups") || !strcmp(variable, "dependent_servicegroup_name")) {
1763 				if(strcmp(value, XODTEMPLATE_NULL)) {
1764 					if((temp_servicedependency->dependent_servicegroup_name = (char *)strdup(value)) == NULL)
1765 						result = ERROR;
1766 					}
1767 				temp_servicedependency->have_dependent_servicegroup_name = TRUE;
1768 				}
1769 			else if(!strcmp(variable, "dependent_hostgroup") || !strcmp(variable, "dependent_hostgroups") || !strcmp(variable, "dependent_hostgroup_name")) {
1770 				if(strcmp(value, XODTEMPLATE_NULL)) {
1771 					if((temp_servicedependency->dependent_hostgroup_name = (char *)strdup(value)) == NULL)
1772 						result = ERROR;
1773 					}
1774 				temp_servicedependency->have_dependent_hostgroup_name = TRUE;
1775 				}
1776 			else if(!strcmp(variable, "dependent_host") || !strcmp(variable, "dependent_host_name")) {
1777 				if(strcmp(value, XODTEMPLATE_NULL)) {
1778 					if((temp_servicedependency->dependent_host_name = (char *)strdup(value)) == NULL)
1779 						result = ERROR;
1780 					}
1781 				temp_servicedependency->have_dependent_host_name = TRUE;
1782 
1783 				/* NOTE: dependencies are added to the skiplist in xodtemplate_duplicate_objects(), except if daemon is using precached config */
1784 				if(result == OK && force_skiplists == TRUE && temp_servicedependency->dependent_host_name != NULL && temp_servicedependency->dependent_service_description != NULL) {
1785 					/* add servicedependency to template skiplist for fast searches */
1786 					result = skiplist_insert(xobject_skiplists[X_SERVICEDEPENDENCY_SKIPLIST], (void *)temp_servicedependency);
1787 					switch(result) {
1788 						case SKIPLIST_OK:
1789 							result = OK;
1790 							break;
1791 						default:
1792 							result = ERROR;
1793 							break;
1794 						}
1795 					}
1796 				}
1797 			else if(!strcmp(variable, "dependent_description") || !strcmp(variable, "dependent_service_description")) {
1798 				if(strcmp(value, XODTEMPLATE_NULL)) {
1799 					if((temp_servicedependency->dependent_service_description = (char *)strdup(value)) == NULL)
1800 						result = ERROR;
1801 					}
1802 				temp_servicedependency->have_dependent_service_description = TRUE;
1803 
1804 				/* NOTE: dependencies are added to the skiplist in xodtemplate_duplicate_objects(), except if daemon is using precached config */
1805 				if(result == OK && force_skiplists == TRUE && temp_servicedependency->dependent_host_name != NULL && temp_servicedependency->dependent_service_description != NULL) {
1806 					/* add servicedependency to template skiplist for fast searches */
1807 					result = skiplist_insert(xobject_skiplists[X_SERVICEDEPENDENCY_SKIPLIST], (void *)temp_servicedependency);
1808 					switch(result) {
1809 						case SKIPLIST_OK:
1810 							result = OK;
1811 							break;
1812 						default:
1813 							result = ERROR;
1814 							break;
1815 						}
1816 					}
1817 				}
1818 			else if(!strcmp(variable, "dependency_period")) {
1819 				if(strcmp(value, XODTEMPLATE_NULL)) {
1820 					if((temp_servicedependency->dependency_period = (char *)strdup(value)) == NULL)
1821 						result = ERROR;
1822 					}
1823 				temp_servicedependency->have_dependency_period = TRUE;
1824 				}
1825 			else if(!strcmp(variable, "inherits_parent")) {
1826 				temp_servicedependency->inherits_parent = (atoi(value) > 0) ? TRUE : FALSE;
1827 				temp_servicedependency->have_inherits_parent = TRUE;
1828 				}
1829 			else if(!strcmp(variable, "execution_failure_options") || !strcmp(variable, "execution_failure_criteria")) {
1830 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
1831 					if(!strcmp(temp_ptr, "o") || !strcmp(temp_ptr, "ok"))
1832 						temp_servicedependency->fail_execute_on_ok = TRUE;
1833 					else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unknown"))
1834 						temp_servicedependency->fail_execute_on_unknown = TRUE;
1835 					else if(!strcmp(temp_ptr, "w") || !strcmp(temp_ptr, "warning"))
1836 						temp_servicedependency->fail_execute_on_warning = TRUE;
1837 					else if(!strcmp(temp_ptr, "c") || !strcmp(temp_ptr, "critical"))
1838 						temp_servicedependency->fail_execute_on_critical = TRUE;
1839 					else if(!strcmp(temp_ptr, "p") || !strcmp(temp_ptr, "pending"))
1840 						temp_servicedependency->fail_execute_on_pending = TRUE;
1841 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
1842 						temp_servicedependency->fail_execute_on_ok = FALSE;
1843 						temp_servicedependency->fail_execute_on_unknown = FALSE;
1844 						temp_servicedependency->fail_execute_on_warning = FALSE;
1845 						temp_servicedependency->fail_execute_on_critical = FALSE;
1846 						}
1847 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
1848 						temp_servicedependency->fail_execute_on_ok = TRUE;
1849 						temp_servicedependency->fail_execute_on_unknown = TRUE;
1850 						temp_servicedependency->fail_execute_on_warning = TRUE;
1851 						temp_servicedependency->fail_execute_on_critical = TRUE;
1852 						}
1853 					else {
1854 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid execution dependency option '%s' in servicedependency definition.\n", temp_ptr);
1855 						return ERROR;
1856 						}
1857 					}
1858 				temp_servicedependency->have_execution_dependency_options = TRUE;
1859 				}
1860 			else if(!strcmp(variable, "notification_failure_options") || !strcmp(variable, "notification_failure_criteria")) {
1861 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
1862 					if(!strcmp(temp_ptr, "o") || !strcmp(temp_ptr, "ok"))
1863 						temp_servicedependency->fail_notify_on_ok = TRUE;
1864 					else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unknown"))
1865 						temp_servicedependency->fail_notify_on_unknown = TRUE;
1866 					else if(!strcmp(temp_ptr, "w") || !strcmp(temp_ptr, "warning"))
1867 						temp_servicedependency->fail_notify_on_warning = TRUE;
1868 					else if(!strcmp(temp_ptr, "c") || !strcmp(temp_ptr, "critical"))
1869 						temp_servicedependency->fail_notify_on_critical = TRUE;
1870 					else if(!strcmp(temp_ptr, "p") || !strcmp(temp_ptr, "pending"))
1871 						temp_servicedependency->fail_notify_on_pending = TRUE;
1872 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
1873 						temp_servicedependency->fail_notify_on_ok = FALSE;
1874 						temp_servicedependency->fail_notify_on_unknown = FALSE;
1875 						temp_servicedependency->fail_notify_on_warning = FALSE;
1876 						temp_servicedependency->fail_notify_on_critical = FALSE;
1877 						temp_servicedependency->fail_notify_on_pending = FALSE;
1878 						}
1879 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
1880 						temp_servicedependency->fail_notify_on_ok = TRUE;
1881 						temp_servicedependency->fail_notify_on_unknown = TRUE;
1882 						temp_servicedependency->fail_notify_on_warning = TRUE;
1883 						temp_servicedependency->fail_notify_on_critical = TRUE;
1884 						temp_servicedependency->fail_notify_on_pending = TRUE;
1885 						}
1886 					else {
1887 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid notification dependency option '%s' in servicedependency definition.\n", temp_ptr);
1888 						return ERROR;
1889 						}
1890 					}
1891 				temp_servicedependency->have_notification_dependency_options = TRUE;
1892 				}
1893 			else if(!strcmp(variable, "register"))
1894 				temp_servicedependency->register_object = (atoi(value) > 0) ? TRUE : FALSE;
1895 			else {
1896 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid servicedependency object directive '%s'.\n", variable);
1897 				return ERROR;
1898 				}
1899 
1900 			break;
1901 
1902 
1903 		case XODTEMPLATE_SERVICEESCALATION:
1904 
1905 			temp_serviceescalation = (xodtemplate_serviceescalation *)xodtemplate_current_object;
1906 
1907 			if(!strcmp(variable, "use")) {
1908 				if((temp_serviceescalation->template = (char *)strdup(value)) == NULL)
1909 					result = ERROR;
1910 				}
1911 			else if(!strcmp(variable, "name")) {
1912 
1913 				if((temp_serviceescalation->name = (char *)strdup(value)) == NULL)
1914 					result = ERROR;
1915 
1916 				if(result == OK) {
1917 					/* add escalation to template skiplist for fast searches */
1918 					result = skiplist_insert(xobject_template_skiplists[X_SERVICEESCALATION_SKIPLIST], (void *)temp_serviceescalation);
1919 					switch(result) {
1920 						case SKIPLIST_ERROR_DUPLICATE:
1921 							logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for service escalation '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_serviceescalation->_config_file), temp_serviceescalation->_start_line);
1922 							result = ERROR;
1923 							break;
1924 						case SKIPLIST_OK:
1925 							result = OK;
1926 							break;
1927 						default:
1928 							result = ERROR;
1929 							break;
1930 						}
1931 					}
1932 				}
1933 			else if(!strcmp(variable, "host") || !strcmp(variable, "host_name")) {
1934 
1935 				if(strcmp(value, XODTEMPLATE_NULL)) {
1936 					if((temp_serviceescalation->host_name = (char *)strdup(value)) == NULL)
1937 						result = ERROR;
1938 					}
1939 				temp_serviceescalation->have_host_name = TRUE;
1940 
1941 				/* NOTE: escalations are added to the skiplist in xodtemplate_duplicate_objects(), except if daemon is using precached config */
1942 				if(result == OK && force_skiplists == TRUE  && temp_serviceescalation->host_name != NULL && temp_serviceescalation->service_description != NULL) {
1943 					/* add serviceescalation to template skiplist for fast searches */
1944 					result = skiplist_insert(xobject_skiplists[X_SERVICEESCALATION_SKIPLIST], (void *)temp_serviceescalation);
1945 					switch(result) {
1946 						case SKIPLIST_OK:
1947 							result = OK;
1948 							break;
1949 						default:
1950 							result = ERROR;
1951 							break;
1952 						}
1953 					}
1954 				}
1955 			else if(!strcmp(variable, "description") || !strcmp(variable, "service_description")) {
1956 				if(strcmp(value, XODTEMPLATE_NULL)) {
1957 					if((temp_serviceescalation->service_description = (char *)strdup(value)) == NULL)
1958 						result = ERROR;
1959 					}
1960 				temp_serviceescalation->have_service_description = TRUE;
1961 
1962 				/* NOTE: escalations are added to the skiplist in xodtemplate_duplicate_objects(), except if daemon is using precached config */
1963 				if(result == OK && force_skiplists == TRUE  && temp_serviceescalation->host_name != NULL && temp_serviceescalation->service_description != NULL) {
1964 					/* add serviceescalation to template skiplist for fast searches */
1965 					result = skiplist_insert(xobject_skiplists[X_SERVICEESCALATION_SKIPLIST], (void *)temp_serviceescalation);
1966 					switch(result) {
1967 						case SKIPLIST_OK:
1968 							result = OK;
1969 							break;
1970 						default:
1971 							result = ERROR;
1972 							break;
1973 						}
1974 					}
1975 				}
1976 			else if(!strcmp(variable, "servicegroup") || !strcmp(variable, "servicegroups") || !strcmp(variable, "servicegroup_name")) {
1977 				if(strcmp(value, XODTEMPLATE_NULL)) {
1978 					if((temp_serviceescalation->servicegroup_name = (char *)strdup(value)) == NULL)
1979 						result = ERROR;
1980 					}
1981 				temp_serviceescalation->have_servicegroup_name = TRUE;
1982 				}
1983 			else if(!strcmp(variable, "hostgroup") || !strcmp(variable, "hostgroups") || !strcmp(variable, "hostgroup_name")) {
1984 				if(strcmp(value, XODTEMPLATE_NULL)) {
1985 					if((temp_serviceescalation->hostgroup_name = (char *)strdup(value)) == NULL)
1986 						result = ERROR;
1987 					}
1988 				temp_serviceescalation->have_hostgroup_name = TRUE;
1989 				}
1990 			else if(!strcmp(variable, "contact_groups")) {
1991 				if(strcmp(value, XODTEMPLATE_NULL)) {
1992 					if((temp_serviceescalation->contact_groups = (char *)strdup(value)) == NULL)
1993 						result = ERROR;
1994 					}
1995 				temp_serviceescalation->have_contact_groups = TRUE;
1996 				}
1997 			else if(!strcmp(variable, "contacts")) {
1998 				if(strcmp(value, XODTEMPLATE_NULL)) {
1999 					if((temp_serviceescalation->contacts = (char *)strdup(value)) == NULL)
2000 						result = ERROR;
2001 					}
2002 				temp_serviceescalation->have_contacts = TRUE;
2003 				}
2004 			else if(!strcmp(variable, "escalation_period")) {
2005 				if(strcmp(value, XODTEMPLATE_NULL)) {
2006 					if((temp_serviceescalation->escalation_period = (char *)strdup(value)) == NULL)
2007 						result = ERROR;
2008 					}
2009 				temp_serviceescalation->have_escalation_period = TRUE;
2010 				}
2011 			else if(!strcmp(variable, "first_notification")) {
2012 				temp_serviceescalation->first_notification = atoi(value);
2013 				temp_serviceescalation->have_first_notification = TRUE;
2014 				}
2015 			else if(!strcmp(variable, "last_notification")) {
2016 				temp_serviceescalation->last_notification = atoi(value);
2017 				temp_serviceescalation->have_last_notification = TRUE;
2018 				}
2019 			else if(!strcmp(variable, "notification_interval")) {
2020 				temp_serviceescalation->notification_interval = strtod(value, NULL);
2021 				temp_serviceescalation->have_notification_interval = TRUE;
2022 				}
2023 			else if(!strcmp(variable, "escalation_options")) {
2024 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
2025 					if(!strcmp(temp_ptr, "w") || !strcmp(temp_ptr, "warning"))
2026 						temp_serviceescalation->escalate_on_warning = TRUE;
2027 					else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unknown"))
2028 						temp_serviceescalation->escalate_on_unknown = TRUE;
2029 					else if(!strcmp(temp_ptr, "c") || !strcmp(temp_ptr, "critical"))
2030 						temp_serviceescalation->escalate_on_critical = TRUE;
2031 					else if(!strcmp(temp_ptr, "r") || !strcmp(temp_ptr, "recovery"))
2032 						temp_serviceescalation->escalate_on_recovery = TRUE;
2033 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
2034 						temp_serviceescalation->escalate_on_warning = FALSE;
2035 						temp_serviceescalation->escalate_on_unknown = FALSE;
2036 						temp_serviceescalation->escalate_on_critical = FALSE;
2037 						temp_serviceescalation->escalate_on_recovery = FALSE;
2038 						}
2039 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
2040 						temp_serviceescalation->escalate_on_warning = TRUE;
2041 						temp_serviceescalation->escalate_on_unknown = TRUE;
2042 						temp_serviceescalation->escalate_on_critical = TRUE;
2043 						temp_serviceescalation->escalate_on_recovery = TRUE;
2044 						}
2045 					else {
2046 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid escalation option '%s' in serviceescalation definition.\n", temp_ptr);
2047 						return ERROR;
2048 						}
2049 					}
2050 				temp_serviceescalation->have_escalation_options = TRUE;
2051 				}
2052 			else if(!strcmp(variable, "register"))
2053 				temp_serviceescalation->register_object = (atoi(value) > 0) ? TRUE : FALSE;
2054 			else {
2055 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid serviceescalation object directive '%s'.\n", variable);
2056 				return ERROR;
2057 				}
2058 
2059 			break;
2060 
2061 
2062 		case XODTEMPLATE_CONTACT:
2063 
2064 			temp_contact = (xodtemplate_contact *)xodtemplate_current_object;
2065 
2066 			if(!strcmp(variable, "use")) {
2067 				if((temp_contact->template = (char *)strdup(value)) == NULL)
2068 					result = ERROR;
2069 				}
2070 			else if(!strcmp(variable, "name")) {
2071 
2072 				if((temp_contact->name = (char *)strdup(value)) == NULL)
2073 					result = ERROR;
2074 
2075 				if(result == OK) {
2076 					/* add contact to template skiplist for fast searches */
2077 					result = skiplist_insert(xobject_template_skiplists[X_CONTACT_SKIPLIST], (void *)temp_contact);
2078 					switch(result) {
2079 						case SKIPLIST_ERROR_DUPLICATE:
2080 							logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for contact '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_contact->_config_file), temp_contact->_start_line);
2081 							result = ERROR;
2082 							break;
2083 						case SKIPLIST_OK:
2084 							result = OK;
2085 							break;
2086 						default:
2087 							result = ERROR;
2088 							break;
2089 						}
2090 					}
2091 				}
2092 			else if(!strcmp(variable, "contact_name")) {
2093 				if((temp_contact->contact_name = (char *)strdup(value)) == NULL)
2094 					result = ERROR;
2095 
2096 				if(result == OK) {
2097 					/* add contact to template skiplist for fast searches */
2098 					result = skiplist_insert(xobject_skiplists[X_CONTACT_SKIPLIST], (void *)temp_contact);
2099 					switch(result) {
2100 						case SKIPLIST_ERROR_DUPLICATE:
2101 							logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for contact '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_contact->_config_file), temp_contact->_start_line);
2102 							result = ERROR;
2103 							break;
2104 						case SKIPLIST_OK:
2105 							result = OK;
2106 							break;
2107 						default:
2108 							result = ERROR;
2109 							break;
2110 						}
2111 					}
2112 				}
2113 			else if(!strcmp(variable, "alias")) {
2114 				if((temp_contact->alias = (char *)strdup(value)) == NULL)
2115 					result = ERROR;
2116 				}
2117 			else if(!strcmp(variable, "contact_groups") || !strcmp(variable, "contactgroups")) {
2118 				if(strcmp(value, XODTEMPLATE_NULL)) {
2119 					if((temp_contact->contact_groups = (char *)strdup(value)) == NULL)
2120 						result = ERROR;
2121 					}
2122 				temp_contact->have_contact_groups = TRUE;
2123 				}
2124 			else if(!strcmp(variable, "email")) {
2125 				if(strcmp(value, XODTEMPLATE_NULL)) {
2126 					if((temp_contact->email = (char *)strdup(value)) == NULL)
2127 						result = ERROR;
2128 					}
2129 				temp_contact->have_email = TRUE;
2130 				}
2131 			else if(!strcmp(variable, "pager")) {
2132 				if(strcmp(value, XODTEMPLATE_NULL)) {
2133 					if((temp_contact->pager = (char *)strdup(value)) == NULL)
2134 						result = ERROR;
2135 					}
2136 				temp_contact->have_pager = TRUE;
2137 				}
2138 			else if(strstr(variable, "address") == variable) {
2139 				x = atoi(variable + 7);
2140 				if(x < 1 || x > MAX_XODTEMPLATE_CONTACT_ADDRESSES)
2141 					result = ERROR;
2142 				else if(strcmp(value, XODTEMPLATE_NULL)) {
2143 					if((temp_contact->address[x - 1] = (char *)strdup(value)) == NULL)
2144 						result = ERROR;
2145 					}
2146 				if(result == OK)
2147 					temp_contact->have_address[x - 1] = TRUE;
2148 				}
2149 			else if(!strcmp(variable, "host_notification_period")) {
2150 				if(strcmp(value, XODTEMPLATE_NULL)) {
2151 					if((temp_contact->host_notification_period = (char *)strdup(value)) == NULL)
2152 						result = ERROR;
2153 					}
2154 				temp_contact->have_host_notification_period = TRUE;
2155 				}
2156 			else if(!strcmp(variable, "host_notification_commands")) {
2157 				if(strcmp(value, XODTEMPLATE_NULL)) {
2158 					if((temp_contact->host_notification_commands = (char *)strdup(value)) == NULL)
2159 						result = ERROR;
2160 					}
2161 				temp_contact->have_host_notification_commands = TRUE;
2162 				}
2163 			else if(!strcmp(variable, "service_notification_period")) {
2164 				if(strcmp(value, XODTEMPLATE_NULL)) {
2165 					if((temp_contact->service_notification_period = (char *)strdup(value)) == NULL)
2166 						result = ERROR;
2167 					}
2168 				temp_contact->have_service_notification_period = TRUE;
2169 				}
2170 			else if(!strcmp(variable, "service_notification_commands")) {
2171 				if(strcmp(value, XODTEMPLATE_NULL)) {
2172 					if((temp_contact->service_notification_commands = (char *)strdup(value)) == NULL)
2173 						result = ERROR;
2174 					}
2175 				temp_contact->have_service_notification_commands = TRUE;
2176 				}
2177 			else if(!strcmp(variable, "host_notification_options")) {
2178 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
2179 					if(!strcmp(temp_ptr, "d") || !strcmp(temp_ptr, "down"))
2180 						temp_contact->notify_on_host_down = TRUE;
2181 					else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unreachable"))
2182 						temp_contact->notify_on_host_unreachable = TRUE;
2183 					else if(!strcmp(temp_ptr, "r") || !strcmp(temp_ptr, "recovery"))
2184 						temp_contact->notify_on_host_recovery = TRUE;
2185 					else if(!strcmp(temp_ptr, "f") || !strcmp(temp_ptr, "flapping"))
2186 						temp_contact->notify_on_host_flapping = TRUE;
2187 					else if(!strcmp(temp_ptr, "s") || !strcmp(temp_ptr, "downtime"))
2188 						temp_contact->notify_on_host_downtime = TRUE;
2189 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
2190 						temp_contact->notify_on_host_down = FALSE;
2191 						temp_contact->notify_on_host_unreachable = FALSE;
2192 						temp_contact->notify_on_host_recovery = FALSE;
2193 						temp_contact->notify_on_host_flapping = FALSE;
2194 						temp_contact->notify_on_host_downtime = FALSE;
2195 						}
2196 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
2197 						temp_contact->notify_on_host_down = TRUE;
2198 						temp_contact->notify_on_host_unreachable = TRUE;
2199 						temp_contact->notify_on_host_recovery = TRUE;
2200 						temp_contact->notify_on_host_flapping = TRUE;
2201 						temp_contact->notify_on_host_downtime = TRUE;
2202 						}
2203 					else {
2204 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid host notification option '%s' in contact definition.\n", temp_ptr);
2205 						return ERROR;
2206 						}
2207 					}
2208 				temp_contact->have_host_notification_options = TRUE;
2209 				}
2210 			else if(!strcmp(variable, "service_notification_options")) {
2211 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
2212 					if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unknown"))
2213 						temp_contact->notify_on_service_unknown = TRUE;
2214 					else if(!strcmp(temp_ptr, "w") || !strcmp(temp_ptr, "warning"))
2215 						temp_contact->notify_on_service_warning = TRUE;
2216 					else if(!strcmp(temp_ptr, "c") || !strcmp(temp_ptr, "critical"))
2217 						temp_contact->notify_on_service_critical = TRUE;
2218 					else if(!strcmp(temp_ptr, "r") || !strcmp(temp_ptr, "recovery"))
2219 						temp_contact->notify_on_service_recovery = TRUE;
2220 					else if(!strcmp(temp_ptr, "f") || !strcmp(temp_ptr, "flapping"))
2221 						temp_contact->notify_on_service_flapping = TRUE;
2222 					else if(!strcmp(temp_ptr, "s") || !strcmp(temp_ptr, "downtime"))
2223 						temp_contact->notify_on_service_downtime = TRUE;
2224 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
2225 						temp_contact->notify_on_service_unknown = FALSE;
2226 						temp_contact->notify_on_service_warning = FALSE;
2227 						temp_contact->notify_on_service_critical = FALSE;
2228 						temp_contact->notify_on_service_recovery = FALSE;
2229 						temp_contact->notify_on_service_flapping = FALSE;
2230 						temp_contact->notify_on_service_downtime = FALSE;
2231 						}
2232 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
2233 						temp_contact->notify_on_service_unknown = TRUE;
2234 						temp_contact->notify_on_service_warning = TRUE;
2235 						temp_contact->notify_on_service_critical = TRUE;
2236 						temp_contact->notify_on_service_recovery = TRUE;
2237 						temp_contact->notify_on_service_flapping = TRUE;
2238 						temp_contact->notify_on_service_downtime = TRUE;
2239 						}
2240 					else {
2241 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid service notification option '%s' in contact definition.\n", temp_ptr);
2242 						return ERROR;
2243 						}
2244 					}
2245 				temp_contact->have_service_notification_options = TRUE;
2246 				}
2247 			else if(!strcmp(variable, "host_notifications_enabled")) {
2248 				temp_contact->host_notifications_enabled = (atoi(value) > 0) ? TRUE : FALSE;
2249 				temp_contact->have_host_notifications_enabled = TRUE;
2250 				}
2251 			else if(!strcmp(variable, "service_notifications_enabled")) {
2252 				temp_contact->service_notifications_enabled = (atoi(value) > 0) ? TRUE : FALSE;
2253 				temp_contact->have_service_notifications_enabled = TRUE;
2254 				}
2255 			else if(!strcmp(variable, "can_submit_commands")) {
2256 				temp_contact->can_submit_commands = (atoi(value) > 0) ? TRUE : FALSE;
2257 				temp_contact->have_can_submit_commands = TRUE;
2258 				}
2259 			else if(!strcmp(variable, "retain_status_information")) {
2260 				temp_contact->retain_status_information = (atoi(value) > 0) ? TRUE : FALSE;
2261 				temp_contact->have_retain_status_information = TRUE;
2262 				}
2263 			else if(!strcmp(variable, "retain_nonstatus_information")) {
2264 				temp_contact->retain_nonstatus_information = (atoi(value) > 0) ? TRUE : FALSE;
2265 				temp_contact->have_retain_nonstatus_information = TRUE;
2266 				}
2267 			else if(!strcmp(variable, "register"))
2268 				temp_contact->register_object = (atoi(value) > 0) ? TRUE : FALSE;
2269 			else if(variable[0] == '_') {
2270 
2271 				/* get the variable name */
2272 				customvarname = (char *)strdup(variable + 1);
2273 
2274 				/* make sure we have a variable name */
2275 				if(customvarname == NULL || !strcmp(customvarname, "")) {
2276 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Null custom variable name.\n");
2277 					my_free(customvarname);
2278 					return ERROR;
2279 					}
2280 
2281 				/* get the variable value */
2282 				if(strcmp(value, XODTEMPLATE_NULL))
2283 					customvarvalue = (char *)strdup(value);
2284 				else
2285 					customvarvalue = NULL;
2286 
2287 				/* add the custom variable */
2288 				if(xodtemplate_add_custom_variable_to_contact(temp_contact, customvarname, customvarvalue) == NULL) {
2289 					my_free(customvarname);
2290 					my_free(customvarvalue);
2291 					return ERROR;
2292 					}
2293 
2294 				/* free memory */
2295 				my_free(customvarname);
2296 				my_free(customvarvalue);
2297 				}
2298 			else {
2299 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid contact object directive '%s'.\n", variable);
2300 				return ERROR;
2301 				}
2302 
2303 			break;
2304 
2305 
2306 		case XODTEMPLATE_HOST:
2307 
2308 			temp_host = (xodtemplate_host *)xodtemplate_current_object;
2309 
2310 			if(!strcmp(variable, "use")) {
2311 				if((temp_host->template = (char *)strdup(value)) == NULL)
2312 					result = ERROR;
2313 				}
2314 			else if(!strcmp(variable, "name")) {
2315 
2316 				if((temp_host->name = (char *)strdup(value)) == NULL)
2317 					result = ERROR;
2318 
2319 				if(result == OK) {
2320 					/* add host to template skiplist for fast searches */
2321 					result = skiplist_insert(xobject_template_skiplists[X_HOST_SKIPLIST], (void *)temp_host);
2322 					switch(result) {
2323 						case SKIPLIST_ERROR_DUPLICATE:
2324 							logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for host '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_host->_config_file), temp_host->_start_line);
2325 							result = ERROR;
2326 							break;
2327 						case SKIPLIST_OK:
2328 							result = OK;
2329 							break;
2330 						default:
2331 							result = ERROR;
2332 							break;
2333 						}
2334 					}
2335 				}
2336 			else if(!strcmp(variable, "host_name")) {
2337 				if((temp_host->host_name = (char *)strdup(value)) == NULL)
2338 					result = ERROR;
2339 
2340 				if(result == OK) {
2341 					/* add host to template skiplist for fast searches */
2342 					result = skiplist_insert(xobject_skiplists[X_HOST_SKIPLIST], (void *)temp_host);
2343 					switch(result) {
2344 						case SKIPLIST_ERROR_DUPLICATE:
2345 							logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for host '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_host->_config_file), temp_host->_start_line);
2346 							result = ERROR;
2347 							break;
2348 						case SKIPLIST_OK:
2349 							result = OK;
2350 							break;
2351 						default:
2352 							result = ERROR;
2353 							break;
2354 						}
2355 					}
2356 				}
2357 			else if(!strcmp(variable, "display_name")) {
2358 				if(strcmp(value, XODTEMPLATE_NULL)) {
2359 					if((temp_host->display_name = (char *)strdup(value)) == NULL)
2360 						result = ERROR;
2361 					}
2362 				temp_host->have_display_name = TRUE;
2363 				}
2364 			else if(!strcmp(variable, "alias")) {
2365 				if((temp_host->alias = (char *)strdup(value)) == NULL)
2366 					result = ERROR;
2367 				}
2368 			else if(!strcmp(variable, "address")) {
2369 				if((temp_host->address = (char *)strdup(value)) == NULL)
2370 					result = ERROR;
2371 				}
2372 			else if(!strcmp(variable, "parents")) {
2373 				if(strcmp(value, XODTEMPLATE_NULL)) {
2374 					if((temp_host->parents = (char *)strdup(value)) == NULL)
2375 						result = ERROR;
2376 					}
2377 				temp_host->have_parents = TRUE;
2378 				}
2379 			else if(!strcmp(variable, "host_groups") || !strcmp(variable, "hostgroups")) {
2380 				if(strcmp(value, XODTEMPLATE_NULL)) {
2381 					if((temp_host->host_groups = (char *)strdup(value)) == NULL)
2382 						result = ERROR;
2383 					}
2384 				temp_host->have_host_groups = TRUE;
2385 				}
2386 			else if(!strcmp(variable, "contact_groups")) {
2387 				if(strcmp(value, XODTEMPLATE_NULL)) {
2388 					if((temp_host->contact_groups = (char *)strdup(value)) == NULL)
2389 						result = ERROR;
2390 					}
2391 				temp_host->have_contact_groups = TRUE;
2392 				}
2393 			else if(!strcmp(variable, "contacts")) {
2394 				if(strcmp(value, XODTEMPLATE_NULL)) {
2395 					if((temp_host->contacts = (char *)strdup(value)) == NULL)
2396 						result = ERROR;
2397 					}
2398 				temp_host->have_contacts = TRUE;
2399 				}
2400 			else if(!strcmp(variable, "notification_period")) {
2401 				if(strcmp(value, XODTEMPLATE_NULL)) {
2402 					if((temp_host->notification_period = (char *)strdup(value)) == NULL)
2403 						result = ERROR;
2404 					}
2405 				temp_host->have_notification_period = TRUE;
2406 				}
2407 			else if(!strcmp(variable, "check_command")) {
2408 				if(strcmp(value, XODTEMPLATE_NULL)) {
2409 					if((temp_host->check_command = (char *)strdup(value)) == NULL)
2410 						result = ERROR;
2411 					}
2412 				temp_host->have_check_command = TRUE;
2413 				}
2414 			else if(!strcmp(variable, "check_period")) {
2415 				if(strcmp(value, XODTEMPLATE_NULL)) {
2416 					if((temp_host->check_period = (char *)strdup(value)) == NULL)
2417 						result = ERROR;
2418 					}
2419 				temp_host->have_check_period = TRUE;
2420 				}
2421 			else if(!strcmp(variable, "event_handler")) {
2422 				if(strcmp(value, XODTEMPLATE_NULL)) {
2423 					if((temp_host->event_handler = (char *)strdup(value)) == NULL)
2424 						result = ERROR;
2425 					}
2426 				temp_host->have_event_handler = TRUE;
2427 				}
2428 			else if(!strcmp(variable, "failure_prediction_options")) {
2429 				if(strcmp(value, XODTEMPLATE_NULL)) {
2430 					if((temp_host->failure_prediction_options = (char *)strdup(value)) == NULL)
2431 						result = ERROR;
2432 					}
2433 				temp_host->have_failure_prediction_options = TRUE;
2434 				}
2435 			else if(!strcmp(variable, "notes")) {
2436 				if(strcmp(value, XODTEMPLATE_NULL)) {
2437 					if((temp_host->notes = (char *)strdup(value)) == NULL)
2438 						result = ERROR;
2439 					}
2440 				temp_host->have_notes = TRUE;
2441 				}
2442 			else if(!strcmp(variable, "notes_url")) {
2443 				if(strcmp(value, XODTEMPLATE_NULL)) {
2444 					if((temp_host->notes_url = (char *)strdup(value)) == NULL)
2445 						result = ERROR;
2446 					}
2447 				temp_host->have_notes_url = TRUE;
2448 				}
2449 			else if(!strcmp(variable, "action_url")) {
2450 				if(strcmp(value, XODTEMPLATE_NULL)) {
2451 					if((temp_host->action_url = (char *)strdup(value)) == NULL)
2452 						result = ERROR;
2453 					}
2454 				temp_host->have_action_url = TRUE;
2455 				}
2456 			else if(!strcmp(variable, "icon_image")) {
2457 				if(strcmp(value, XODTEMPLATE_NULL)) {
2458 					if((temp_host->icon_image = (char *)strdup(value)) == NULL)
2459 						result = ERROR;
2460 					}
2461 				temp_host->have_icon_image = TRUE;
2462 				}
2463 			else if(!strcmp(variable, "icon_image_alt")) {
2464 				if(strcmp(value, XODTEMPLATE_NULL)) {
2465 					if((temp_host->icon_image_alt = (char *)strdup(value)) == NULL)
2466 						result = ERROR;
2467 					}
2468 				temp_host->have_icon_image_alt = TRUE;
2469 				}
2470 			else if(!strcmp(variable, "vrml_image")) {
2471 				if(strcmp(value, XODTEMPLATE_NULL)) {
2472 					if((temp_host->vrml_image = (char *)strdup(value)) == NULL)
2473 						result = ERROR;
2474 					}
2475 				temp_host->have_vrml_image = TRUE;
2476 				}
2477 			else if(!strcmp(variable, "gd2_image") || !strcmp(variable, "statusmap_image")) {
2478 				if(strcmp(value, XODTEMPLATE_NULL)) {
2479 					if((temp_host->statusmap_image = (char *)strdup(value)) == NULL)
2480 						result = ERROR;
2481 					}
2482 				temp_host->have_statusmap_image = TRUE;
2483 				}
2484 			else if(!strcmp(variable, "initial_state")) {
2485 				if(!strcmp(value, "o") || !strcmp(value, "up"))
2486 					temp_host->initial_state = 0; /* HOST_UP */
2487 				else if(!strcmp(value, "d") || !strcmp(value, "down"))
2488 					temp_host->initial_state = 1; /* HOST_DOWN */
2489 				else if(!strcmp(value, "u") || !strcmp(value, "unreachable"))
2490 					temp_host->initial_state = 2; /* HOST_UNREACHABLE */
2491 				else {
2492 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid initial state '%s' in host definition.\n", value);
2493 					result = ERROR;
2494 					}
2495 				temp_host->have_initial_state = TRUE;
2496 				}
2497 			else if(!strcmp(variable, "check_interval") || !strcmp(variable, "normal_check_interval")) {
2498 				temp_host->check_interval = strtod(value, NULL);
2499 				temp_host->have_check_interval = TRUE;
2500 				}
2501 			else if(!strcmp(variable, "retry_interval") || !strcmp(variable, "retry_check_interval")) {
2502 				temp_host->retry_interval = strtod(value, NULL);
2503 				temp_host->have_retry_interval = TRUE;
2504 				}
2505 			else if(!strcmp(variable, "max_check_attempts")) {
2506 				temp_host->max_check_attempts = atoi(value);
2507 				temp_host->have_max_check_attempts = TRUE;
2508 				}
2509 			else if(!strcmp(variable, "checks_enabled") || !strcmp(variable, "active_checks_enabled")) {
2510 				temp_host->active_checks_enabled = (atoi(value) > 0) ? TRUE : FALSE;
2511 				temp_host->have_active_checks_enabled = TRUE;
2512 				}
2513 			else if(!strcmp(variable, "passive_checks_enabled")) {
2514 				temp_host->passive_checks_enabled = (atoi(value) > 0) ? TRUE : FALSE;
2515 				temp_host->have_passive_checks_enabled = TRUE;
2516 				}
2517 			else if(!strcmp(variable, "event_handler_enabled")) {
2518 				temp_host->event_handler_enabled = (atoi(value) > 0) ? TRUE : FALSE;
2519 				temp_host->have_event_handler_enabled = TRUE;
2520 				}
2521 			else if(!strcmp(variable, "check_freshness")) {
2522 				temp_host->check_freshness = (atoi(value) > 0) ? TRUE : FALSE;
2523 				temp_host->have_check_freshness = TRUE;
2524 				}
2525 			else if(!strcmp(variable, "freshness_threshold")) {
2526 				temp_host->freshness_threshold = atoi(value);
2527 				temp_host->have_freshness_threshold = TRUE;
2528 				}
2529 			else if(!strcmp(variable, "low_flap_threshold")) {
2530 				temp_host->low_flap_threshold = strtod(value, NULL);
2531 				temp_host->have_low_flap_threshold = TRUE;
2532 				}
2533 			else if(!strcmp(variable, "high_flap_threshold")) {
2534 				temp_host->high_flap_threshold = strtod(value, NULL);
2535 				temp_host->have_high_flap_threshold = TRUE;
2536 				}
2537 			else if(!strcmp(variable, "flap_detection_enabled")) {
2538 				temp_host->flap_detection_enabled = (atoi(value) > 0) ? TRUE : FALSE;
2539 				temp_host->have_flap_detection_enabled = TRUE;
2540 				}
2541 			else if(!strcmp(variable, "flap_detection_options")) {
2542 
2543 				/* user is specifying something, so discard defaults... */
2544 				temp_host->flap_detection_on_up = FALSE;
2545 				temp_host->flap_detection_on_down = FALSE;
2546 				temp_host->flap_detection_on_unreachable = FALSE;
2547 
2548 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
2549 					if(!strcmp(temp_ptr, "o") || !strcmp(temp_ptr, "up"))
2550 						temp_host->flap_detection_on_up = TRUE;
2551 					else if(!strcmp(temp_ptr, "d") || !strcmp(temp_ptr, "down"))
2552 						temp_host->flap_detection_on_down = TRUE;
2553 					else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unreachable"))
2554 						temp_host->flap_detection_on_unreachable = TRUE;
2555 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
2556 						temp_host->flap_detection_on_up = FALSE;
2557 						temp_host->flap_detection_on_down = FALSE;
2558 						temp_host->flap_detection_on_unreachable = FALSE;
2559 						}
2560 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
2561 						temp_host->flap_detection_on_up = TRUE;
2562 						temp_host->flap_detection_on_down = TRUE;
2563 						temp_host->flap_detection_on_unreachable = TRUE;
2564 						}
2565 					else {
2566 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid flap detection option '%s' in host definition.\n", temp_ptr);
2567 						result = ERROR;
2568 						}
2569 					}
2570 				temp_host->have_flap_detection_options = TRUE;
2571 				}
2572 			else if(!strcmp(variable, "notification_options")) {
2573 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
2574 					if(!strcmp(temp_ptr, "d") || !strcmp(temp_ptr, "down"))
2575 						temp_host->notify_on_down = TRUE;
2576 					else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unreachable"))
2577 						temp_host->notify_on_unreachable = TRUE;
2578 					else if(!strcmp(temp_ptr, "r") || !strcmp(temp_ptr, "recovery"))
2579 						temp_host->notify_on_recovery = TRUE;
2580 					else if(!strcmp(temp_ptr, "f") || !strcmp(temp_ptr, "flapping"))
2581 						temp_host->notify_on_flapping = TRUE;
2582 					else if(!strcmp(temp_ptr, "s") || !strcmp(temp_ptr, "downtime"))
2583 						temp_host->notify_on_downtime = TRUE;
2584 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
2585 						temp_host->notify_on_down = FALSE;
2586 						temp_host->notify_on_unreachable = FALSE;
2587 						temp_host->notify_on_recovery = FALSE;
2588 						temp_host->notify_on_flapping = FALSE;
2589 						temp_host->notify_on_downtime = FALSE;
2590 						}
2591 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
2592 						temp_host->notify_on_down = TRUE;
2593 						temp_host->notify_on_unreachable = TRUE;
2594 						temp_host->notify_on_recovery = TRUE;
2595 						temp_host->notify_on_flapping = TRUE;
2596 						temp_host->notify_on_downtime = TRUE;
2597 						}
2598 					else {
2599 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid notification option '%s' in host definition.\n", temp_ptr);
2600 						result = ERROR;
2601 						}
2602 					}
2603 				temp_host->have_notification_options = TRUE;
2604 				}
2605 			else if(!strcmp(variable, "notifications_enabled")) {
2606 				temp_host->notifications_enabled = (atoi(value) > 0) ? TRUE : FALSE;
2607 				temp_host->have_notifications_enabled = TRUE;
2608 				}
2609 			else if(!strcmp(variable, "notification_interval")) {
2610 				temp_host->notification_interval = strtod(value, NULL);
2611 				temp_host->have_notification_interval = TRUE;
2612 				}
2613 			else if(!strcmp(variable, "first_notification_delay")) {
2614 				temp_host->first_notification_delay = strtod(value, NULL);
2615 				temp_host->have_first_notification_delay = TRUE;
2616 				}
2617 			else if(!strcmp(variable, "stalking_options")) {
2618 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
2619 					if(!strcmp(temp_ptr, "o") || !strcmp(temp_ptr, "up"))
2620 						temp_host->stalk_on_up = TRUE;
2621 					else if(!strcmp(temp_ptr, "d") || !strcmp(temp_ptr, "down"))
2622 						temp_host->stalk_on_down = TRUE;
2623 					else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unreachable"))
2624 						temp_host->stalk_on_unreachable = TRUE;
2625 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
2626 						temp_host->stalk_on_up = FALSE;
2627 						temp_host->stalk_on_down = FALSE;
2628 						temp_host->stalk_on_unreachable = FALSE;
2629 						}
2630 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
2631 						temp_host->stalk_on_up = TRUE;
2632 						temp_host->stalk_on_down = TRUE;
2633 						temp_host->stalk_on_unreachable = TRUE;
2634 						}
2635 					else {
2636 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid stalking option '%s' in host definition.\n", temp_ptr);
2637 						result = ERROR;
2638 						}
2639 					}
2640 				temp_host->have_stalking_options = TRUE;
2641 				}
2642 			else if(!strcmp(variable, "process_perf_data")) {
2643 				temp_host->process_perf_data = (atoi(value) > 0) ? TRUE : FALSE;
2644 				temp_host->have_process_perf_data = TRUE;
2645 				}
2646 			else if(!strcmp(variable, "failure_prediction_enabled")) {
2647 				temp_host->failure_prediction_enabled = (atoi(value) > 0) ? TRUE : FALSE;
2648 				temp_host->have_failure_prediction_enabled = TRUE;
2649 				}
2650 			else if(!strcmp(variable, "2d_coords")) {
2651 				if((temp_ptr = strtok(value, ", ")) == NULL) {
2652 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 2d_coords value '%s' in host definition.\n", temp_ptr);
2653 					return ERROR;
2654 					}
2655 				temp_host->x_2d = atoi(temp_ptr);
2656 				if((temp_ptr = strtok(NULL, ", ")) == NULL) {
2657 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 2d_coords value '%s' in host definition.\n", temp_ptr);
2658 					return ERROR;
2659 					}
2660 				temp_host->y_2d = atoi(temp_ptr);
2661 				temp_host->have_2d_coords = TRUE;
2662 				}
2663 			else if(!strcmp(variable, "3d_coords")) {
2664 				if((temp_ptr = strtok(value, ", ")) == NULL) {
2665 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 3d_coords value '%s' in host definition.\n", temp_ptr);
2666 					return ERROR;
2667 					}
2668 				temp_host->x_3d = strtod(temp_ptr, NULL);
2669 				if((temp_ptr = strtok(NULL, ", ")) == NULL) {
2670 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 3d_coords value '%s' in host definition.\n", temp_ptr);
2671 					return ERROR;
2672 					}
2673 				temp_host->y_3d = strtod(temp_ptr, NULL);
2674 				if((temp_ptr = strtok(NULL, ", ")) == NULL) {
2675 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 3d_coords value '%s' in host definition.\n", temp_ptr);
2676 					return ERROR;
2677 					}
2678 				temp_host->z_3d = strtod(temp_ptr, NULL);
2679 				temp_host->have_3d_coords = TRUE;
2680 				}
2681 			else if(!strcmp(variable, "obsess_over_host")) {
2682 				temp_host->obsess_over_host = (atoi(value) > 0) ? TRUE : FALSE;
2683 				temp_host->have_obsess_over_host = TRUE;
2684 				}
2685 			else if(!strcmp(variable, "retain_status_information")) {
2686 				temp_host->retain_status_information = (atoi(value) > 0) ? TRUE : FALSE;
2687 				temp_host->have_retain_status_information = TRUE;
2688 				}
2689 			else if(!strcmp(variable, "retain_nonstatus_information")) {
2690 				temp_host->retain_nonstatus_information = (atoi(value) > 0) ? TRUE : FALSE;
2691 				temp_host->have_retain_nonstatus_information = TRUE;
2692 				}
2693 			else if(!strcmp(variable, "register"))
2694 				temp_host->register_object = (atoi(value) > 0) ? TRUE : FALSE;
2695 			else if(variable[0] == '_') {
2696 
2697 				/* get the variable name */
2698 				customvarname = (char *)strdup(variable + 1);
2699 
2700 				/* make sure we have a variable name */
2701 				if(customvarname == NULL || !strcmp(customvarname, "")) {
2702 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Null custom variable name.\n");
2703 					my_free(customvarname);
2704 					return ERROR;
2705 					}
2706 
2707 				/* get the variable value */
2708 				customvarvalue = NULL;
2709 				if(strcmp(value, XODTEMPLATE_NULL))
2710 					customvarvalue = (char *)strdup(value);
2711 
2712 				/* add the custom variable */
2713 				if(xodtemplate_add_custom_variable_to_host(temp_host, customvarname, customvarvalue) == NULL) {
2714 					my_free(customvarname);
2715 					my_free(customvarvalue);
2716 					return ERROR;
2717 					}
2718 
2719 				/* free memory */
2720 				my_free(customvarname);
2721 				my_free(customvarvalue);
2722 				}
2723 			else {
2724 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid host object directive '%s'.\n", variable);
2725 				return ERROR;
2726 				}
2727 
2728 			break;
2729 
2730 		case XODTEMPLATE_SERVICE:
2731 
2732 			temp_service = (xodtemplate_service *)xodtemplate_current_object;
2733 
2734 			if(!strcmp(variable, "use")) {
2735 				if((temp_service->template = (char *)strdup(value)) == NULL)
2736 					result = ERROR;
2737 				}
2738 			else if(!strcmp(variable, "name")) {
2739 
2740 				if((temp_service->name = (char *)strdup(value)) == NULL)
2741 					result = ERROR;
2742 
2743 				if(result == OK) {
2744 					/* add service to template skiplist for fast searches */
2745 					result = skiplist_insert(xobject_template_skiplists[X_SERVICE_SKIPLIST], (void *)temp_service);
2746 					switch(result) {
2747 						case SKIPLIST_ERROR_DUPLICATE:
2748 							logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for service '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_service->_config_file), temp_service->_start_line);
2749 							result = ERROR;
2750 							break;
2751 						case SKIPLIST_OK:
2752 							result = OK;
2753 							break;
2754 						default:
2755 							result = ERROR;
2756 							break;
2757 						}
2758 					}
2759 				}
2760 			else if(!strcmp(variable, "host") || !strcmp(variable, "hosts") || !strcmp(variable, "host_name")) {
2761 				if(strcmp(value, XODTEMPLATE_NULL)) {
2762 					if((temp_service->host_name = (char *)strdup(value)) == NULL)
2763 						result = ERROR;
2764 					}
2765 				temp_service->have_host_name = TRUE;
2766 
2767 				/* NOTE: services are added to the skiplist in xodtemplate_duplicate_services(), except if daemon is using precached config */
2768 				if(result == OK && force_skiplists == TRUE  && temp_service->host_name != NULL && temp_service->service_description != NULL) {
2769 					/* add service to template skiplist for fast searches */
2770 					result = skiplist_insert(xobject_skiplists[X_SERVICE_SKIPLIST], (void *)temp_service);
2771 					switch(result) {
2772 						case SKIPLIST_ERROR_DUPLICATE:
2773 							logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for service '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_service->_config_file), temp_service->_start_line);
2774 							result = ERROR;
2775 							break;
2776 						case SKIPLIST_OK:
2777 							result = OK;
2778 							break;
2779 						default:
2780 							result = ERROR;
2781 							break;
2782 						}
2783 					}
2784 				}
2785 			else if(!strcmp(variable, "service_description") || !strcmp(variable, "description")) {
2786 				if(strcmp(value, XODTEMPLATE_NULL)) {
2787 					if((temp_service->service_description = (char *)strdup(value)) == NULL)
2788 						result = ERROR;
2789 					}
2790 				temp_service->have_service_description = TRUE;
2791 
2792 				/* NOTE: services are added to the skiplist in xodtemplate_duplicate_services(), except if daemon is using precached config */
2793 				if(result == OK && force_skiplists == TRUE  && temp_service->host_name != NULL && temp_service->service_description != NULL) {
2794 					/* add service to template skiplist for fast searches */
2795 					result = skiplist_insert(xobject_skiplists[X_SERVICE_SKIPLIST], (void *)temp_service);
2796 					switch(result) {
2797 						case SKIPLIST_ERROR_DUPLICATE:
2798 							logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for service '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_service->_config_file), temp_service->_start_line);
2799 							result = ERROR;
2800 							break;
2801 						case SKIPLIST_OK:
2802 							result = OK;
2803 							break;
2804 						default:
2805 							result = ERROR;
2806 							break;
2807 						}
2808 					}
2809 				}
2810 			else if(!strcmp(variable, "display_name")) {
2811 				if(strcmp(value, XODTEMPLATE_NULL)) {
2812 					if((temp_service->display_name = (char *)strdup(value)) == NULL)
2813 						result = ERROR;
2814 					}
2815 				temp_service->have_display_name = TRUE;
2816 				}
2817 			else if(!strcmp(variable, "hostgroup") || !strcmp(variable, "hostgroups") || !strcmp(variable, "hostgroup_name")) {
2818 				if(strcmp(value, XODTEMPLATE_NULL)) {
2819 					if((temp_service->hostgroup_name = (char *)strdup(value)) == NULL)
2820 						result = ERROR;
2821 					}
2822 				temp_service->have_hostgroup_name = TRUE;
2823 				}
2824 			else if(!strcmp(variable, "service_groups") || !strcmp(variable, "servicegroups")) {
2825 				if(strcmp(value, XODTEMPLATE_NULL)) {
2826 					if((temp_service->service_groups = (char *)strdup(value)) == NULL)
2827 						result = ERROR;
2828 					}
2829 				temp_service->have_service_groups = TRUE;
2830 				}
2831 			else if(!strcmp(variable, "check_command")) {
2832 				if(strcmp(value, XODTEMPLATE_NULL)) {
2833 					if(value[0] == '!') {
2834 						temp_service->have_important_check_command = TRUE;
2835 						temp_ptr = value + 1;
2836 						}
2837 					else
2838 						temp_ptr = value;
2839 					if((temp_service->check_command = (char *)strdup(temp_ptr)) == NULL)
2840 						result = ERROR;
2841 					}
2842 				temp_service->have_check_command = TRUE;
2843 				}
2844 			else if(!strcmp(variable, "check_period")) {
2845 				if(strcmp(value, XODTEMPLATE_NULL)) {
2846 					if((temp_service->check_period = (char *)strdup(value)) == NULL)
2847 						result = ERROR;
2848 					}
2849 				temp_service->have_check_period = TRUE;
2850 				}
2851 			else if(!strcmp(variable, "event_handler")) {
2852 				if(strcmp(value, XODTEMPLATE_NULL)) {
2853 					if((temp_service->event_handler = (char *)strdup(value)) == NULL)
2854 						result = ERROR;
2855 					}
2856 				temp_service->have_event_handler = TRUE;
2857 				}
2858 			else if(!strcmp(variable, "notification_period")) {
2859 				if(strcmp(value, XODTEMPLATE_NULL)) {
2860 					if((temp_service->notification_period = (char *)strdup(value)) == NULL)
2861 						result = ERROR;
2862 					}
2863 				temp_service->have_notification_period = TRUE;
2864 				}
2865 			else if(!strcmp(variable, "contact_groups")) {
2866 				if(strcmp(value, XODTEMPLATE_NULL)) {
2867 					if((temp_service->contact_groups = (char *)strdup(value)) == NULL)
2868 						result = ERROR;
2869 					}
2870 				temp_service->have_contact_groups = TRUE;
2871 				}
2872 			else if(!strcmp(variable, "contacts")) {
2873 				if(strcmp(value, XODTEMPLATE_NULL)) {
2874 					if((temp_service->contacts = (char *)strdup(value)) == NULL)
2875 						result = ERROR;
2876 					}
2877 				temp_service->have_contacts = TRUE;
2878 				}
2879 			else if(!strcmp(variable, "failure_prediction_options")) {
2880 				if(strcmp(value, XODTEMPLATE_NULL)) {
2881 					if((temp_service->failure_prediction_options = (char *)strdup(value)) == NULL)
2882 						result = ERROR;
2883 					}
2884 				temp_service->have_failure_prediction_options = TRUE;
2885 				}
2886 			else if(!strcmp(variable, "notes")) {
2887 				if(strcmp(value, XODTEMPLATE_NULL)) {
2888 					if((temp_service->notes = (char *)strdup(value)) == NULL)
2889 						result = ERROR;
2890 					}
2891 				temp_service->have_notes = TRUE;
2892 				}
2893 			else if(!strcmp(variable, "notes_url")) {
2894 				if(strcmp(value, XODTEMPLATE_NULL)) {
2895 					if((temp_service->notes_url = (char *)strdup(value)) == NULL)
2896 						result = ERROR;
2897 					}
2898 				temp_service->have_notes_url = TRUE;
2899 				}
2900 			else if(!strcmp(variable, "action_url")) {
2901 				if(strcmp(value, XODTEMPLATE_NULL)) {
2902 					if((temp_service->action_url = (char *)strdup(value)) == NULL)
2903 						result = ERROR;
2904 					}
2905 				temp_service->have_action_url = TRUE;
2906 				}
2907 			else if(!strcmp(variable, "icon_image")) {
2908 				if(strcmp(value, XODTEMPLATE_NULL)) {
2909 					if((temp_service->icon_image = (char *)strdup(value)) == NULL)
2910 						result = ERROR;
2911 					}
2912 				temp_service->have_icon_image = TRUE;
2913 				}
2914 			else if(!strcmp(variable, "icon_image_alt")) {
2915 				if(strcmp(value, XODTEMPLATE_NULL)) {
2916 					if((temp_service->icon_image_alt = (char *)strdup(value)) == NULL)
2917 						result = ERROR;
2918 					}
2919 				temp_service->have_icon_image_alt = TRUE;
2920 				}
2921 			else if(!strcmp(variable, "initial_state")) {
2922 				if(!strcmp(value, "o") || !strcmp(value, "ok"))
2923 					temp_service->initial_state = STATE_OK;
2924 				else if(!strcmp(value, "w") || !strcmp(value, "warning"))
2925 					temp_service->initial_state = STATE_WARNING;
2926 				else if(!strcmp(value, "u") || !strcmp(value, "unknown"))
2927 					temp_service->initial_state = STATE_UNKNOWN;
2928 				else if(!strcmp(value, "c") || !strcmp(value, "critical"))
2929 					temp_service->initial_state = STATE_CRITICAL;
2930 				else {
2931 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid initial state '%s' in service definition.\n", value);
2932 					result = ERROR;
2933 					}
2934 				temp_service->have_initial_state = TRUE;
2935 				}
2936 			else if(!strcmp(variable, "max_check_attempts")) {
2937 				temp_service->max_check_attempts = atoi(value);
2938 				temp_service->have_max_check_attempts = TRUE;
2939 				}
2940 			else if(!strcmp(variable, "check_interval") || !strcmp(variable, "normal_check_interval")) {
2941 				temp_service->check_interval = strtod(value, NULL);
2942 				temp_service->have_check_interval = TRUE;
2943 				}
2944 			else if(!strcmp(variable, "retry_interval") || !strcmp(variable, "retry_check_interval")) {
2945 				temp_service->retry_interval = strtod(value, NULL);
2946 				temp_service->have_retry_interval = TRUE;
2947 				}
2948 			else if(!strcmp(variable, "active_checks_enabled")) {
2949 				temp_service->active_checks_enabled = (atoi(value) > 0) ? TRUE : FALSE;
2950 				temp_service->have_active_checks_enabled = TRUE;
2951 				}
2952 			else if(!strcmp(variable, "passive_checks_enabled")) {
2953 				temp_service->passive_checks_enabled = (atoi(value) > 0) ? TRUE : FALSE;
2954 				temp_service->have_passive_checks_enabled = TRUE;
2955 				}
2956 			else if(!strcmp(variable, "parallelize_check")) {
2957 				temp_service->parallelize_check = atoi(value);
2958 				temp_service->have_parallelize_check = TRUE;
2959 				}
2960 			else if(!strcmp(variable, "is_volatile")) {
2961 				temp_service->is_volatile = (atoi(value) > 0) ? TRUE : FALSE;
2962 				temp_service->have_is_volatile = TRUE;
2963 				}
2964 			else if(!strcmp(variable, "obsess_over_service")) {
2965 				temp_service->obsess_over_service = (atoi(value) > 0) ? TRUE : FALSE;
2966 				temp_service->have_obsess_over_service = TRUE;
2967 				}
2968 			else if(!strcmp(variable, "event_handler_enabled")) {
2969 				temp_service->event_handler_enabled = (atoi(value) > 0) ? TRUE : FALSE;
2970 				temp_service->have_event_handler_enabled = TRUE;
2971 				}
2972 			else if(!strcmp(variable, "check_freshness")) {
2973 				temp_service->check_freshness = (atoi(value) > 0) ? TRUE : FALSE;
2974 				temp_service->have_check_freshness = TRUE;
2975 				}
2976 			else if(!strcmp(variable, "freshness_threshold")) {
2977 				temp_service->freshness_threshold = atoi(value);
2978 				temp_service->have_freshness_threshold = TRUE;
2979 				}
2980 			else if(!strcmp(variable, "low_flap_threshold")) {
2981 				temp_service->low_flap_threshold = strtod(value, NULL);
2982 				temp_service->have_low_flap_threshold = TRUE;
2983 				}
2984 			else if(!strcmp(variable, "high_flap_threshold")) {
2985 				temp_service->high_flap_threshold = strtod(value, NULL);
2986 				temp_service->have_high_flap_threshold = TRUE;
2987 				}
2988 			else if(!strcmp(variable, "flap_detection_enabled")) {
2989 				temp_service->flap_detection_enabled = (atoi(value) > 0) ? TRUE : FALSE;
2990 				temp_service->have_flap_detection_enabled = TRUE;
2991 				}
2992 			else if(!strcmp(variable, "flap_detection_options")) {
2993 
2994 				/* user is specifying something, so discard defaults... */
2995 				temp_service->flap_detection_on_ok = FALSE;
2996 				temp_service->flap_detection_on_warning = FALSE;
2997 				temp_service->flap_detection_on_unknown = FALSE;
2998 				temp_service->flap_detection_on_critical = FALSE;
2999 
3000 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
3001 					if(!strcmp(temp_ptr, "o") || !strcmp(temp_ptr, "ok"))
3002 						temp_service->flap_detection_on_ok = TRUE;
3003 					else if(!strcmp(temp_ptr, "w") || !strcmp(temp_ptr, "warning"))
3004 						temp_service->flap_detection_on_warning = TRUE;
3005 					else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unknown"))
3006 						temp_service->flap_detection_on_unknown = TRUE;
3007 					else if(!strcmp(temp_ptr, "c") || !strcmp(temp_ptr, "critical"))
3008 						temp_service->flap_detection_on_critical = TRUE;
3009 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
3010 						temp_service->flap_detection_on_ok = FALSE;
3011 						temp_service->flap_detection_on_warning = FALSE;
3012 						temp_service->flap_detection_on_unknown = FALSE;
3013 						temp_service->flap_detection_on_critical = FALSE;
3014 						}
3015 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
3016 						temp_service->flap_detection_on_ok = TRUE;
3017 						temp_service->flap_detection_on_warning = TRUE;
3018 						temp_service->flap_detection_on_unknown = TRUE;
3019 						temp_service->flap_detection_on_critical = TRUE;
3020 						}
3021 					else {
3022 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid flap detection option '%s' in service definition.\n", temp_ptr);
3023 						return ERROR;
3024 						}
3025 					}
3026 				temp_service->have_flap_detection_options = TRUE;
3027 				}
3028 			else if(!strcmp(variable, "notification_options")) {
3029 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
3030 					if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unknown"))
3031 						temp_service->notify_on_unknown = TRUE;
3032 					else if(!strcmp(temp_ptr, "w") || !strcmp(temp_ptr, "warning"))
3033 						temp_service->notify_on_warning = TRUE;
3034 					else if(!strcmp(temp_ptr, "c") || !strcmp(temp_ptr, "critical"))
3035 						temp_service->notify_on_critical = TRUE;
3036 					else if(!strcmp(temp_ptr, "r") || !strcmp(temp_ptr, "recovery"))
3037 						temp_service->notify_on_recovery = TRUE;
3038 					else if(!strcmp(temp_ptr, "f") || !strcmp(temp_ptr, "flapping"))
3039 						temp_service->notify_on_flapping = TRUE;
3040 					else if(!strcmp(temp_ptr, "s") || !strcmp(temp_ptr, "downtime"))
3041 						temp_service->notify_on_downtime = TRUE;
3042 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
3043 						temp_service->notify_on_unknown = FALSE;
3044 						temp_service->notify_on_warning = FALSE;
3045 						temp_service->notify_on_critical = FALSE;
3046 						temp_service->notify_on_recovery = FALSE;
3047 						temp_service->notify_on_flapping = FALSE;
3048 						temp_service->notify_on_downtime = FALSE;
3049 						}
3050 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
3051 						temp_service->notify_on_unknown = TRUE;
3052 						temp_service->notify_on_warning = TRUE;
3053 						temp_service->notify_on_critical = TRUE;
3054 						temp_service->notify_on_recovery = TRUE;
3055 						temp_service->notify_on_flapping = TRUE;
3056 						temp_service->notify_on_downtime = TRUE;
3057 						}
3058 					else {
3059 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid notification option '%s' in service definition.\n", temp_ptr);
3060 						return ERROR;
3061 						}
3062 					}
3063 				temp_service->have_notification_options = TRUE;
3064 				}
3065 			else if(!strcmp(variable, "notifications_enabled")) {
3066 				temp_service->notifications_enabled = (atoi(value) > 0) ? TRUE : FALSE;
3067 				temp_service->have_notifications_enabled = TRUE;
3068 				}
3069 			else if(!strcmp(variable, "notification_interval")) {
3070 				temp_service->notification_interval = strtod(value, NULL);
3071 				temp_service->have_notification_interval = TRUE;
3072 				}
3073 			else if(!strcmp(variable, "first_notification_delay")) {
3074 				temp_service->first_notification_delay = strtod(value, NULL);
3075 				temp_service->have_first_notification_delay = TRUE;
3076 				}
3077 			else if(!strcmp(variable, "stalking_options")) {
3078 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
3079 					if(!strcmp(temp_ptr, "o") || !strcmp(temp_ptr, "ok"))
3080 						temp_service->stalk_on_ok = TRUE;
3081 					else if(!strcmp(temp_ptr, "w") || !strcmp(temp_ptr, "warning"))
3082 						temp_service->stalk_on_warning = TRUE;
3083 					else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unknown"))
3084 						temp_service->stalk_on_unknown = TRUE;
3085 					else if(!strcmp(temp_ptr, "c") || !strcmp(temp_ptr, "critical"))
3086 						temp_service->stalk_on_critical = TRUE;
3087 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
3088 						temp_service->stalk_on_ok = FALSE;
3089 						temp_service->stalk_on_warning = FALSE;
3090 						temp_service->stalk_on_unknown = FALSE;
3091 						temp_service->stalk_on_critical = FALSE;
3092 						}
3093 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
3094 						temp_service->stalk_on_ok = TRUE;
3095 						temp_service->stalk_on_warning = TRUE;
3096 						temp_service->stalk_on_unknown = TRUE;
3097 						temp_service->stalk_on_critical = TRUE;
3098 						}
3099 					else {
3100 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid stalking option '%s' in service definition.\n", temp_ptr);
3101 						return ERROR;
3102 						}
3103 					}
3104 				temp_service->have_stalking_options = TRUE;
3105 				}
3106 			else if(!strcmp(variable, "process_perf_data")) {
3107 				temp_service->process_perf_data = (atoi(value) > 0) ? TRUE : FALSE;
3108 				temp_service->have_process_perf_data = TRUE;
3109 				}
3110 			else if(!strcmp(variable, "failure_prediction_enabled")) {
3111 				temp_service->failure_prediction_enabled = (atoi(value) > 0) ? TRUE : FALSE;
3112 				temp_service->have_failure_prediction_enabled = TRUE;
3113 				}
3114 			else if(!strcmp(variable, "retain_status_information")) {
3115 				temp_service->retain_status_information = (atoi(value) > 0) ? TRUE : FALSE;
3116 				temp_service->have_retain_status_information = TRUE;
3117 				}
3118 			else if(!strcmp(variable, "retain_nonstatus_information")) {
3119 				temp_service->retain_nonstatus_information = (atoi(value) > 0) ? TRUE : FALSE;
3120 				temp_service->have_retain_nonstatus_information = TRUE;
3121 				}
3122 			else if(!strcmp(variable, "register"))
3123 				temp_service->register_object = (atoi(value) > 0) ? TRUE : FALSE;
3124 			else if(variable[0] == '_') {
3125 
3126 				/* get the variable name */
3127 				customvarname = (char *)strdup(variable + 1);
3128 
3129 				/* make sure we have a variable name */
3130 				if(customvarname == NULL || !strcmp(customvarname, "")) {
3131 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Null custom variable name.\n");
3132 					my_free(customvarname);
3133 					return ERROR;
3134 					}
3135 
3136 				/* get the variable value */
3137 				if(strcmp(value, XODTEMPLATE_NULL))
3138 					customvarvalue = (char *)strdup(value);
3139 				else
3140 					customvarvalue = NULL;
3141 
3142 				/* add the custom variable */
3143 				if(xodtemplate_add_custom_variable_to_service(temp_service, customvarname, customvarvalue) == NULL) {
3144 					my_free(customvarname);
3145 					my_free(customvarvalue);
3146 					return ERROR;
3147 					}
3148 
3149 				/* free memory */
3150 				my_free(customvarname);
3151 				my_free(customvarvalue);
3152 				}
3153 			else {
3154 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid service object directive '%s'.\n", variable);
3155 				return ERROR;
3156 				}
3157 
3158 			break;
3159 
3160 		case XODTEMPLATE_HOSTDEPENDENCY:
3161 
3162 			temp_hostdependency = (xodtemplate_hostdependency *)xodtemplate_current_object;
3163 
3164 			if(!strcmp(variable, "use")) {
3165 				if((temp_hostdependency->template = (char *)strdup(value)) == NULL)
3166 					result = ERROR;
3167 				}
3168 			else if(!strcmp(variable, "name")) {
3169 
3170 				if((temp_hostdependency->name = (char *)strdup(value)) == NULL)
3171 					result = ERROR;
3172 
3173 				if(result == OK) {
3174 					/* add dependency to template skiplist for fast searches */
3175 					result = skiplist_insert(xobject_template_skiplists[X_HOSTDEPENDENCY_SKIPLIST], (void *)temp_hostdependency);
3176 					switch(result) {
3177 						case SKIPLIST_ERROR_DUPLICATE:
3178 							logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for host dependency '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_hostdependency->_config_file), temp_hostdependency->_start_line);
3179 							result = ERROR;
3180 							break;
3181 						case SKIPLIST_OK:
3182 							result = OK;
3183 							break;
3184 						default:
3185 							result = ERROR;
3186 							break;
3187 						}
3188 					}
3189 				}
3190 			else if(!strcmp(variable, "hostgroup") || !strcmp(variable, "hostgroups") || !strcmp(variable, "hostgroup_name")) {
3191 				if(strcmp(value, XODTEMPLATE_NULL)) {
3192 					if((temp_hostdependency->hostgroup_name = (char *)strdup(value)) == NULL)
3193 						result = ERROR;
3194 					}
3195 				temp_hostdependency->have_hostgroup_name = TRUE;
3196 				}
3197 			else if(!strcmp(variable, "host") || !strcmp(variable, "host_name") || !strcmp(variable, "master_host") || !strcmp(variable, "master_host_name")) {
3198 				if(strcmp(value, XODTEMPLATE_NULL)) {
3199 					if((temp_hostdependency->host_name = (char *)strdup(value)) == NULL)
3200 						result = ERROR;
3201 					}
3202 				temp_hostdependency->have_host_name = TRUE;
3203 				}
3204 			else if(!strcmp(variable, "dependent_hostgroup") || !strcmp(variable, "dependent_hostgroups") || !strcmp(variable, "dependent_hostgroup_name")) {
3205 				if(strcmp(value, XODTEMPLATE_NULL)) {
3206 					if((temp_hostdependency->dependent_hostgroup_name = (char *)strdup(value)) == NULL)
3207 						result = ERROR;
3208 					}
3209 				temp_hostdependency->have_dependent_hostgroup_name = TRUE;
3210 				}
3211 			else if(!strcmp(variable, "dependent_host") || !strcmp(variable, "dependent_host_name")) {
3212 				if(strcmp(value, XODTEMPLATE_NULL)) {
3213 					if((temp_hostdependency->dependent_host_name = (char *)strdup(value)) == NULL)
3214 						result = ERROR;
3215 					}
3216 				temp_hostdependency->have_dependent_host_name = TRUE;
3217 
3218 				/* NOTE: dependencies are added to the skiplist in xodtemplate_duplicate_objects(), except if daemon is using precached config */
3219 				if(result == OK && force_skiplists == TRUE) {
3220 					/* add hostdependency to template skiplist for fast searches */
3221 					result = skiplist_insert(xobject_skiplists[X_HOSTDEPENDENCY_SKIPLIST], (void *)temp_hostdependency);
3222 					switch(result) {
3223 						case SKIPLIST_OK:
3224 							result = OK;
3225 							break;
3226 						default:
3227 							result = ERROR;
3228 							break;
3229 						}
3230 					}
3231 				}
3232 			else if(!strcmp(variable, "dependency_period")) {
3233 				if(strcmp(value, XODTEMPLATE_NULL)) {
3234 					if((temp_hostdependency->dependency_period = (char *)strdup(value)) == NULL)
3235 						result = ERROR;
3236 					}
3237 				temp_hostdependency->have_dependency_period = TRUE;
3238 				}
3239 			else if(!strcmp(variable, "inherits_parent")) {
3240 				temp_hostdependency->inherits_parent = (atoi(value) > 0) ? TRUE : FALSE;
3241 				temp_hostdependency->have_inherits_parent = TRUE;
3242 				}
3243 			else if(!strcmp(variable, "notification_failure_options") || !strcmp(variable, "notification_failure_criteria")) {
3244 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
3245 					if(!strcmp(temp_ptr, "o") || !strcmp(temp_ptr, "up"))
3246 						temp_hostdependency->fail_notify_on_up = TRUE;
3247 					else if(!strcmp(temp_ptr, "d") || !strcmp(temp_ptr, "down"))
3248 						temp_hostdependency->fail_notify_on_down = TRUE;
3249 					else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unreachable"))
3250 						temp_hostdependency->fail_notify_on_unreachable = TRUE;
3251 					else if(!strcmp(temp_ptr, "p") || !strcmp(temp_ptr, "pending"))
3252 						temp_hostdependency->fail_notify_on_pending = TRUE;
3253 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
3254 						temp_hostdependency->fail_notify_on_up = FALSE;
3255 						temp_hostdependency->fail_notify_on_down = FALSE;
3256 						temp_hostdependency->fail_notify_on_unreachable = FALSE;
3257 						temp_hostdependency->fail_notify_on_pending = FALSE;
3258 						}
3259 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
3260 						temp_hostdependency->fail_notify_on_up = TRUE;
3261 						temp_hostdependency->fail_notify_on_down = TRUE;
3262 						temp_hostdependency->fail_notify_on_unreachable = TRUE;
3263 						temp_hostdependency->fail_notify_on_pending = TRUE;
3264 						}
3265 					else {
3266 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid notification dependency option '%s' in hostdependency definition.\n", temp_ptr);
3267 						return ERROR;
3268 						}
3269 					}
3270 				temp_hostdependency->have_notification_dependency_options = TRUE;
3271 				}
3272 			else if(!strcmp(variable, "execution_failure_options") || !strcmp(variable, "execution_failure_criteria")) {
3273 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
3274 					if(!strcmp(temp_ptr, "o") || !strcmp(temp_ptr, "up"))
3275 						temp_hostdependency->fail_execute_on_up = TRUE;
3276 					else if(!strcmp(temp_ptr, "d") || !strcmp(temp_ptr, "down"))
3277 						temp_hostdependency->fail_execute_on_down = TRUE;
3278 					else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unreachable"))
3279 						temp_hostdependency->fail_execute_on_unreachable = TRUE;
3280 					else if(!strcmp(temp_ptr, "p") || !strcmp(temp_ptr, "pending"))
3281 						temp_hostdependency->fail_execute_on_pending = TRUE;
3282 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
3283 						temp_hostdependency->fail_execute_on_up = FALSE;
3284 						temp_hostdependency->fail_execute_on_down = FALSE;
3285 						temp_hostdependency->fail_execute_on_unreachable = FALSE;
3286 						temp_hostdependency->fail_execute_on_pending = FALSE;
3287 						}
3288 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
3289 						temp_hostdependency->fail_execute_on_up = TRUE;
3290 						temp_hostdependency->fail_execute_on_down = TRUE;
3291 						temp_hostdependency->fail_execute_on_unreachable = TRUE;
3292 						temp_hostdependency->fail_execute_on_pending = TRUE;
3293 						}
3294 					else {
3295 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid execution dependency option '%s' in hostdependency definition.\n", temp_ptr);
3296 						return ERROR;
3297 						}
3298 					}
3299 				temp_hostdependency->have_execution_dependency_options = TRUE;
3300 				}
3301 			else if(!strcmp(variable, "register"))
3302 				temp_hostdependency->register_object = (atoi(value) > 0) ? TRUE : FALSE;
3303 			else {
3304 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid hostdependency object directive '%s'.\n", variable);
3305 				return ERROR;
3306 				}
3307 
3308 			break;
3309 
3310 
3311 		case XODTEMPLATE_HOSTESCALATION:
3312 
3313 			temp_hostescalation = (xodtemplate_hostescalation *)xodtemplate_current_object;
3314 
3315 			if(!strcmp(variable, "use")) {
3316 				if((temp_hostescalation->template = (char *)strdup(value)) == NULL)
3317 					result = ERROR;
3318 				}
3319 			else if(!strcmp(variable, "name")) {
3320 
3321 				if((temp_hostescalation->name = (char *)strdup(value)) == NULL)
3322 					result = ERROR;
3323 
3324 				if(result == OK) {
3325 					/* add escalation to template skiplist for fast searches */
3326 					result = skiplist_insert(xobject_template_skiplists[X_HOSTESCALATION_SKIPLIST], (void *)temp_hostescalation);
3327 					switch(result) {
3328 						case SKIPLIST_ERROR_DUPLICATE:
3329 							logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for host escalation '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_hostescalation->_config_file), temp_hostescalation->_start_line);
3330 							result = ERROR;
3331 							break;
3332 						case SKIPLIST_OK:
3333 							result = OK;
3334 							break;
3335 						default:
3336 							result = ERROR;
3337 							break;
3338 						}
3339 					}
3340 				}
3341 			else if(!strcmp(variable, "hostgroup") || !strcmp(variable, "hostgroups") || !strcmp(variable, "hostgroup_name")) {
3342 				if(strcmp(value, XODTEMPLATE_NULL)) {
3343 					if((temp_hostescalation->hostgroup_name = (char *)strdup(value)) == NULL)
3344 						result = ERROR;
3345 					}
3346 				temp_hostescalation->have_hostgroup_name = TRUE;
3347 				}
3348 			else if(!strcmp(variable, "host") || !strcmp(variable, "host_name")) {
3349 				if(strcmp(value, XODTEMPLATE_NULL)) {
3350 					if((temp_hostescalation->host_name = (char *)strdup(value)) == NULL)
3351 						result = ERROR;
3352 					}
3353 				temp_hostescalation->have_host_name = TRUE;
3354 
3355 				/* NOTE: escalations are added to the skiplist in xodtemplate_duplicate_objects(), except if daemon is using precached config */
3356 				if(result == OK && force_skiplists == TRUE) {
3357 					/* add hostescalation to template skiplist for fast searches */
3358 					result = skiplist_insert(xobject_skiplists[X_HOSTESCALATION_SKIPLIST], (void *)temp_hostescalation);
3359 					switch(result) {
3360 						case SKIPLIST_OK:
3361 							result = OK;
3362 							break;
3363 						default:
3364 							result = ERROR;
3365 							break;
3366 						}
3367 					}
3368 				}
3369 			else if(!strcmp(variable, "contact_groups")) {
3370 				if(strcmp(value, XODTEMPLATE_NULL)) {
3371 					if((temp_hostescalation->contact_groups = (char *)strdup(value)) == NULL)
3372 						result = ERROR;
3373 					}
3374 				temp_hostescalation->have_contact_groups = TRUE;
3375 				}
3376 			else if(!strcmp(variable, "contacts")) {
3377 				if(strcmp(value, XODTEMPLATE_NULL)) {
3378 					if((temp_hostescalation->contacts = (char *)strdup(value)) == NULL)
3379 						result = ERROR;
3380 					}
3381 				temp_hostescalation->have_contacts = TRUE;
3382 				}
3383 			else if(!strcmp(variable, "escalation_period")) {
3384 				if(strcmp(value, XODTEMPLATE_NULL)) {
3385 					if((temp_hostescalation->escalation_period = (char *)strdup(value)) == NULL)
3386 						result = ERROR;
3387 					}
3388 				temp_hostescalation->have_escalation_period = TRUE;
3389 				}
3390 			else if(!strcmp(variable, "first_notification")) {
3391 				temp_hostescalation->first_notification = atoi(value);
3392 				temp_hostescalation->have_first_notification = TRUE;
3393 				}
3394 			else if(!strcmp(variable, "last_notification")) {
3395 				temp_hostescalation->last_notification = atoi(value);
3396 				temp_hostescalation->have_last_notification = TRUE;
3397 				}
3398 			else if(!strcmp(variable, "notification_interval")) {
3399 				temp_hostescalation->notification_interval = strtod(value, NULL);
3400 				temp_hostescalation->have_notification_interval = TRUE;
3401 				}
3402 			else if(!strcmp(variable, "escalation_options")) {
3403 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
3404 					if(!strcmp(temp_ptr, "d") || !strcmp(temp_ptr, "down"))
3405 						temp_hostescalation->escalate_on_down = TRUE;
3406 					else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unreachable"))
3407 						temp_hostescalation->escalate_on_unreachable = TRUE;
3408 					else if(!strcmp(temp_ptr, "r") || !strcmp(temp_ptr, "recovery"))
3409 						temp_hostescalation->escalate_on_recovery = TRUE;
3410 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
3411 						temp_hostescalation->escalate_on_down = FALSE;
3412 						temp_hostescalation->escalate_on_unreachable = FALSE;
3413 						temp_hostescalation->escalate_on_recovery = FALSE;
3414 						}
3415 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
3416 						temp_hostescalation->escalate_on_down = TRUE;
3417 						temp_hostescalation->escalate_on_unreachable = TRUE;
3418 						temp_hostescalation->escalate_on_recovery = TRUE;
3419 						}
3420 					else {
3421 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid escalation option '%s' in hostescalation definition.\n", temp_ptr);
3422 						return ERROR;
3423 						}
3424 					}
3425 				temp_hostescalation->have_escalation_options = TRUE;
3426 				}
3427 			else if(!strcmp(variable, "register"))
3428 				temp_hostescalation->register_object = (atoi(value) > 0) ? TRUE : FALSE;
3429 			else {
3430 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid hostescalation object directive '%s'.\n", variable);
3431 				return ERROR;
3432 				}
3433 
3434 			break;
3435 
3436 		case XODTEMPLATE_HOSTEXTINFO:
3437 
3438 			temp_hostextinfo = xodtemplate_hostextinfo_list;
3439 
3440 			if(!strcmp(variable, "use")) {
3441 				if((temp_hostextinfo->template = (char *)strdup(value)) == NULL)
3442 					result = ERROR;
3443 				}
3444 			else if(!strcmp(variable, "name")) {
3445 
3446 				if((temp_hostextinfo->name = (char *)strdup(value)) == NULL)
3447 					result = ERROR;
3448 
3449 				if(result == OK) {
3450 					/* add to template skiplist for fast searches */
3451 					result = skiplist_insert(xobject_template_skiplists[X_HOSTEXTINFO_SKIPLIST], (void *)temp_hostextinfo);
3452 					switch(result) {
3453 						case SKIPLIST_ERROR_DUPLICATE:
3454 							logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for extended host info '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_hostextinfo->_config_file), temp_hostextinfo->_start_line);
3455 							result = ERROR;
3456 							break;
3457 						case SKIPLIST_OK:
3458 							result = OK;
3459 							break;
3460 						default:
3461 							result = ERROR;
3462 							break;
3463 						}
3464 					}
3465 				}
3466 			else if(!strcmp(variable, "host_name")) {
3467 				if(strcmp(value, XODTEMPLATE_NULL)) {
3468 					if((temp_hostextinfo->host_name = (char *)strdup(value)) == NULL)
3469 						result = ERROR;
3470 					}
3471 				temp_hostextinfo->have_host_name = TRUE;
3472 				}
3473 			else if(!strcmp(variable, "hostgroup") || !strcmp(variable, "hostgroup_name")) {
3474 				if(strcmp(value, XODTEMPLATE_NULL)) {
3475 					if((temp_hostextinfo->hostgroup_name = (char *)strdup(value)) == NULL)
3476 						result = ERROR;
3477 					}
3478 				temp_hostextinfo->have_hostgroup_name = TRUE;
3479 				}
3480 			else if(!strcmp(variable, "notes")) {
3481 				if(strcmp(value, XODTEMPLATE_NULL)) {
3482 					if((temp_hostextinfo->notes = (char *)strdup(value)) == NULL)
3483 						result = ERROR;
3484 					}
3485 				temp_hostextinfo->have_notes = TRUE;
3486 				}
3487 			else if(!strcmp(variable, "notes_url")) {
3488 				if(strcmp(value, XODTEMPLATE_NULL)) {
3489 					if((temp_hostextinfo->notes_url = (char *)strdup(value)) == NULL)
3490 						result = ERROR;
3491 					}
3492 				temp_hostextinfo->have_notes_url = TRUE;
3493 				}
3494 			else if(!strcmp(variable, "action_url")) {
3495 				if(strcmp(value, XODTEMPLATE_NULL)) {
3496 					if((temp_hostextinfo->action_url = (char *)strdup(value)) == NULL)
3497 						result = ERROR;
3498 					}
3499 				temp_hostextinfo->have_action_url = TRUE;
3500 				}
3501 			else if(!strcmp(variable, "icon_image")) {
3502 				if(strcmp(value, XODTEMPLATE_NULL)) {
3503 					if((temp_hostextinfo->icon_image = (char *)strdup(value)) == NULL)
3504 						result = ERROR;
3505 					}
3506 				temp_hostextinfo->have_icon_image = TRUE;
3507 				}
3508 			else if(!strcmp(variable, "icon_image_alt")) {
3509 				if(strcmp(value, XODTEMPLATE_NULL)) {
3510 					if((temp_hostextinfo->icon_image_alt = (char *)strdup(value)) == NULL)
3511 						result = ERROR;
3512 					}
3513 				temp_hostextinfo->have_icon_image_alt = TRUE;
3514 				}
3515 			else if(!strcmp(variable, "vrml_image")) {
3516 				if(strcmp(value, XODTEMPLATE_NULL)) {
3517 					if((temp_hostextinfo->vrml_image = (char *)strdup(value)) == NULL)
3518 						result = ERROR;
3519 					}
3520 				temp_hostextinfo->have_vrml_image = TRUE;
3521 				}
3522 			else if(!strcmp(variable, "gd2_image") || !strcmp(variable, "statusmap_image")) {
3523 				if(strcmp(value, XODTEMPLATE_NULL)) {
3524 					if((temp_hostextinfo->statusmap_image = (char *)strdup(value)) == NULL)
3525 						result = ERROR;
3526 					}
3527 				temp_hostextinfo->have_statusmap_image = TRUE;
3528 				}
3529 			else if(!strcmp(variable, "2d_coords")) {
3530 				temp_ptr = strtok(value, ", ");
3531 				if(temp_ptr == NULL) {
3532 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 2d_coords value '%s' in extended host info definition.\n", temp_ptr);
3533 					return ERROR;
3534 					}
3535 				temp_hostextinfo->x_2d = atoi(temp_ptr);
3536 				temp_ptr = strtok(NULL, ", ");
3537 				if(temp_ptr == NULL) {
3538 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 2d_coords value '%s' in extended host info definition.\n", temp_ptr);
3539 					return ERROR;
3540 					}
3541 				temp_hostextinfo->y_2d = atoi(temp_ptr);
3542 				temp_hostextinfo->have_2d_coords = TRUE;
3543 				}
3544 			else if(!strcmp(variable, "3d_coords")) {
3545 				temp_ptr = strtok(value, ", ");
3546 				if(temp_ptr == NULL) {
3547 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 3d_coords value '%s' in extended host info definition.\n", temp_ptr);
3548 					return ERROR;
3549 					}
3550 				temp_hostextinfo->x_3d = strtod(temp_ptr, NULL);
3551 				temp_ptr = strtok(NULL, ", ");
3552 				if(temp_ptr == NULL) {
3553 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 3d_coords value '%s' in extended host info definition.\n", temp_ptr);
3554 					return ERROR;
3555 					}
3556 				temp_hostextinfo->y_3d = strtod(temp_ptr, NULL);
3557 				temp_ptr = strtok(NULL, ", ");
3558 				if(temp_ptr == NULL) {
3559 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 3d_coords value '%s' in extended host info definition.\n", temp_ptr);
3560 					return ERROR;
3561 					}
3562 				temp_hostextinfo->z_3d = strtod(temp_ptr, NULL);
3563 				temp_hostextinfo->have_3d_coords = TRUE;
3564 				}
3565 			else if(!strcmp(variable, "register"))
3566 				temp_hostextinfo->register_object = (atoi(value) > 0) ? TRUE : FALSE;
3567 			else {
3568 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid hostextinfo object directive '%s'.\n", variable);
3569 				return ERROR;
3570 				}
3571 
3572 			break;
3573 
3574 		case XODTEMPLATE_SERVICEEXTINFO:
3575 
3576 			temp_serviceextinfo = xodtemplate_serviceextinfo_list;
3577 
3578 			if(!strcmp(variable, "use")) {
3579 				if((temp_serviceextinfo->template = (char *)strdup(value)) == NULL)
3580 					result = ERROR;
3581 				}
3582 			else if(!strcmp(variable, "name")) {
3583 
3584 				if((temp_serviceextinfo->name = (char *)strdup(value)) == NULL)
3585 					result = ERROR;
3586 
3587 				if(result == OK) {
3588 					/* add to template skiplist for fast searches */
3589 					result = skiplist_insert(xobject_template_skiplists[X_SERVICEEXTINFO_SKIPLIST], (void *)temp_serviceextinfo);
3590 					switch(result) {
3591 						case SKIPLIST_ERROR_DUPLICATE:
3592 							logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for extended service info '%s' (config file '%s', starting on line %d)\n", value, xodtemplate_config_file_name(temp_serviceextinfo->_config_file), temp_serviceextinfo->_start_line);
3593 							result = ERROR;
3594 							break;
3595 						case SKIPLIST_OK:
3596 							result = OK;
3597 							break;
3598 						default:
3599 							result = ERROR;
3600 							break;
3601 						}
3602 					}
3603 				}
3604 			else if(!strcmp(variable, "host_name")) {
3605 				if(strcmp(value, XODTEMPLATE_NULL)) {
3606 					if((temp_serviceextinfo->host_name = (char *)strdup(value)) == NULL)
3607 						result = ERROR;
3608 					}
3609 				temp_serviceextinfo->have_host_name = TRUE;
3610 				}
3611 			else if(!strcmp(variable, "hostgroup") || !strcmp(variable, "hostgroup_name")) {
3612 				if(strcmp(value, XODTEMPLATE_NULL)) {
3613 					if((temp_serviceextinfo->hostgroup_name = (char *)strdup(value)) == NULL)
3614 						result = ERROR;
3615 					}
3616 				temp_serviceextinfo->have_hostgroup_name = TRUE;
3617 				}
3618 			else if(!strcmp(variable, "service_description")) {
3619 				if(strcmp(value, XODTEMPLATE_NULL)) {
3620 					if((temp_serviceextinfo->service_description = (char *)strdup(value)) == NULL)
3621 						result = ERROR;
3622 					}
3623 				temp_serviceextinfo->have_service_description = TRUE;
3624 				}
3625 			else if(!strcmp(variable, "notes")) {
3626 				if(strcmp(value, XODTEMPLATE_NULL)) {
3627 					if((temp_serviceextinfo->notes = (char *)strdup(value)) == NULL)
3628 						result = ERROR;
3629 					}
3630 				temp_serviceextinfo->have_notes = TRUE;
3631 				}
3632 			else if(!strcmp(variable, "notes_url")) {
3633 				if(strcmp(value, XODTEMPLATE_NULL)) {
3634 					if((temp_serviceextinfo->notes_url = (char *)strdup(value)) == NULL)
3635 						result = ERROR;
3636 					}
3637 				temp_serviceextinfo->have_notes_url = TRUE;
3638 				}
3639 			else if(!strcmp(variable, "action_url")) {
3640 				if(strcmp(value, XODTEMPLATE_NULL)) {
3641 					if((temp_serviceextinfo->action_url = (char *)strdup(value)) == NULL)
3642 						result = ERROR;
3643 					}
3644 				temp_serviceextinfo->have_action_url = TRUE;
3645 				}
3646 			else if(!strcmp(variable, "icon_image")) {
3647 				if(strcmp(value, XODTEMPLATE_NULL)) {
3648 					if((temp_serviceextinfo->icon_image = (char *)strdup(value)) == NULL)
3649 						result = ERROR;
3650 					}
3651 				temp_serviceextinfo->have_icon_image = TRUE;
3652 				}
3653 			else if(!strcmp(variable, "icon_image_alt")) {
3654 				if(strcmp(value, XODTEMPLATE_NULL)) {
3655 					if((temp_serviceextinfo->icon_image_alt = (char *)strdup(value)) == NULL)
3656 						result = ERROR;
3657 					}
3658 				temp_serviceextinfo->have_icon_image_alt = TRUE;
3659 				}
3660 			else if(!strcmp(variable, "register"))
3661 				temp_serviceextinfo->register_object = (atoi(value) > 0) ? TRUE : FALSE;
3662 			else {
3663 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid serviceextinfo object directive '%s'.\n", variable);
3664 				return ERROR;
3665 				}
3666 
3667 			break;
3668 
3669 		default:
3670 			return ERROR;
3671 			break;
3672 		}
3673 
3674 	/* free memory */
3675 	my_free(variable);
3676 	my_free(value);
3677 
3678 	return result;
3679 	}
3680 
3681 
3682 
3683 /* completes an object definition */
xodtemplate_end_object_definition(int options)3684 int xodtemplate_end_object_definition(int options) {
3685 	int result = OK;
3686 
3687 
3688 	xodtemplate_current_object = NULL;
3689 	xodtemplate_current_object_type = XODTEMPLATE_NONE;
3690 
3691 	return result;
3692 	}
3693 
3694 
3695 
3696 /* adds a custom variable to a host */
xodtemplate_add_custom_variable_to_host(xodtemplate_host * hst,char * varname,char * varvalue)3697 xodtemplate_customvariablesmember *xodtemplate_add_custom_variable_to_host(xodtemplate_host *hst, char *varname, char *varvalue) {
3698 
3699 	return xodtemplate_add_custom_variable_to_object(&hst->custom_variables, varname, varvalue);
3700 	}
3701 
3702 
3703 
3704 /* adds a custom variable to a service */
xodtemplate_add_custom_variable_to_service(xodtemplate_service * svc,char * varname,char * varvalue)3705 xodtemplate_customvariablesmember *xodtemplate_add_custom_variable_to_service(xodtemplate_service *svc, char *varname, char *varvalue) {
3706 
3707 	return xodtemplate_add_custom_variable_to_object(&svc->custom_variables, varname, varvalue);
3708 	}
3709 
3710 
3711 
3712 /* adds a custom variable to a contact */
xodtemplate_add_custom_variable_to_contact(xodtemplate_contact * cntct,char * varname,char * varvalue)3713 xodtemplate_customvariablesmember *xodtemplate_add_custom_variable_to_contact(xodtemplate_contact *cntct, char *varname, char *varvalue) {
3714 
3715 	return xodtemplate_add_custom_variable_to_object(&cntct->custom_variables, varname, varvalue);
3716 	}
3717 
3718 
3719 
3720 /* adds a custom variable to an object */
xodtemplate_add_custom_variable_to_object(xodtemplate_customvariablesmember ** object_ptr,char * varname,char * varvalue)3721 xodtemplate_customvariablesmember *xodtemplate_add_custom_variable_to_object(xodtemplate_customvariablesmember **object_ptr, char *varname, char *varvalue) {
3722 	xodtemplate_customvariablesmember *new_customvariablesmember = NULL;
3723 	register int x = 0;
3724 
3725 	/* make sure we have the data we need */
3726 	if(object_ptr == NULL)
3727 		return NULL;
3728 
3729 	if(varname == NULL || !strcmp(varname, ""))
3730 		return NULL;
3731 
3732 	/* allocate memory for a new member */
3733 	if((new_customvariablesmember = malloc(sizeof(xodtemplate_customvariablesmember))) == NULL)
3734 		return NULL;
3735 	if((new_customvariablesmember->variable_name = (char *)strdup(varname)) == NULL) {
3736 		my_free(new_customvariablesmember);
3737 		return NULL;
3738 		}
3739 	if(varvalue) {
3740 		if((new_customvariablesmember->variable_value = (char *)strdup(varvalue)) == NULL) {
3741 			my_free(new_customvariablesmember->variable_name);
3742 			my_free(new_customvariablesmember);
3743 			return NULL;
3744 			}
3745 		}
3746 	else
3747 		new_customvariablesmember->variable_value = NULL;
3748 
3749 	/* convert varname to all uppercase (saves CPU time during macro functions) */
3750 	for(x = 0; new_customvariablesmember->variable_name[x] != '\x0'; x++)
3751 		new_customvariablesmember->variable_name[x] = toupper(new_customvariablesmember->variable_name[x]);
3752 
3753 	/* add the new member to the head of the member list */
3754 	new_customvariablesmember->next = *object_ptr;
3755 	*object_ptr = new_customvariablesmember;
3756 
3757 	return new_customvariablesmember;
3758 	}
3759 
3760 
3761 
3762 /* parses a timeperod directive... :-) */
xodtemplate_parse_timeperiod_directive(xodtemplate_timeperiod * tperiod,char * var,char * val)3763 int xodtemplate_parse_timeperiod_directive(xodtemplate_timeperiod *tperiod, char *var, char *val) {
3764 	char *input = NULL;
3765 	char temp_buffer[5][MAX_INPUT_BUFFER] = {"", "", "", "", ""};
3766 	int items = 0;
3767 	int result = OK;
3768 
3769 	int syear = 0;
3770 	int smon = 0;
3771 	int smday = 0;
3772 	int swday = 0;
3773 	int swday_offset = 0;
3774 	int eyear = 0;
3775 	int emon = 0;
3776 	int emday = 0;
3777 	int ewday = 0;
3778 	int ewday_offset = 0;
3779 	int skip_interval = 0;
3780 
3781 	/* make sure we've got the reqs */
3782 	if(tperiod == NULL || var == NULL || val == NULL)
3783 		return ERROR;
3784 
3785 	/* we'll need the full (unsplit) input later */
3786 	if((input = (char *)malloc(strlen(var) + strlen(val) + 2)) == NULL)
3787 		return ERROR;
3788 	strcpy(input, var);
3789 	strcat(input, " ");
3790 	strcat(input, val);
3791 
3792 	if(0)
3793 		return OK;
3794 
3795 	/* calendar dates */
3796 	else if((items = sscanf(input, "%4d-%2d-%2d - %4d-%2d-%2d / %d %[0-9:, -]", &syear, &smon, &smday, &eyear, &emon, &emday, &skip_interval, temp_buffer[0])) == 8) {
3797 		/* add timerange exception */
3798 		if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_CALENDAR_DATE, syear, smon - 1, smday, 0, 0, eyear, emon - 1, emday, 0, 0, skip_interval, temp_buffer[0]) == NULL)
3799 			result = ERROR;
3800 		}
3801 
3802 	else if((items = sscanf(input, "%4d-%2d-%2d / %d %[0-9:, -]", &syear, &smon, &smday, &skip_interval, temp_buffer[0])) == 5) {
3803 		eyear = syear;
3804 		emon = smon;
3805 		emday = smday;
3806 		/* add timerange exception */
3807 		if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_CALENDAR_DATE, syear, smon - 1, smday, 0, 0, eyear, emon - 1, emday, 0, 0, skip_interval, temp_buffer[0]) == NULL)
3808 			result = ERROR;
3809 		}
3810 
3811 	else if((items = sscanf(input, "%4d-%2d-%2d - %4d-%2d-%2d %[0-9:, -]", &syear, &smon, &smday, &eyear, &emon, &emday, temp_buffer[0])) == 7) {
3812 		/* add timerange exception */
3813 		if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_CALENDAR_DATE, syear, smon - 1, smday, 0, 0, eyear, emon - 1, emday, 0, 0, 0, temp_buffer[0]) == NULL)
3814 			result = ERROR;
3815 		}
3816 
3817 	else if((items = sscanf(input, "%4d-%2d-%2d %[0-9:, -]", &syear, &smon, &smday, temp_buffer[0])) == 4) {
3818 		eyear = syear;
3819 		emon = smon;
3820 		emday = smday;
3821 		/* add timerange exception */
3822 		if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_CALENDAR_DATE, syear, smon - 1, smday, 0, 0, eyear, emon - 1, emday, 0, 0, 0, temp_buffer[0]) == NULL)
3823 			result = ERROR;
3824 		}
3825 
3826 	/* other types... */
3827 	else if((items = sscanf(input, "%[a-z] %d %[a-z] - %[a-z] %d %[a-z] / %d %[0-9:, -]", temp_buffer[0], &swday_offset, temp_buffer[1], temp_buffer[2], &ewday_offset, temp_buffer[3], &skip_interval, temp_buffer[4])) == 8) {
3828 		/* wednesday 1 january - thursday 2 july / 3 */
3829 		if((result = xodtemplate_get_weekday_from_string(temp_buffer[0], &swday)) == OK && (result = xodtemplate_get_month_from_string(temp_buffer[1], &smon)) == OK && (result = xodtemplate_get_weekday_from_string(temp_buffer[2], &ewday)) == OK && (result = xodtemplate_get_month_from_string(temp_buffer[3], &emon)) == OK) {
3830 			/* add timeperiod exception */
3831 			if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_WEEK_DAY, 0, smon, 0, swday, swday_offset, 0, emon, 0, ewday, ewday_offset, skip_interval, temp_buffer[4]) == NULL)
3832 				result = ERROR;
3833 			}
3834 		}
3835 
3836 	else if((items = sscanf(input, "%[a-z] %d - %[a-z] %d / %d %[0-9:, -]", temp_buffer[0], &smday, temp_buffer[1], &emday, &skip_interval, temp_buffer[2])) == 6) {
3837 		/* february 1 - march 15 / 3 */
3838 		/* monday 2 - thursday 3 / 2 */
3839 		/* day 4 - day 6 / 2 */
3840 		if((result = xodtemplate_get_weekday_from_string(temp_buffer[0], &swday)) == OK && (result = xodtemplate_get_weekday_from_string(temp_buffer[1], &ewday)) == OK) {
3841 			/* monday 2 - thursday 3 / 2 */
3842 			swday_offset = smday;
3843 			ewday_offset = emday;
3844 			/* add timeperiod exception */
3845 			if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_WEEK_DAY, 0, 0, 0, swday, swday_offset, 0, 0, 0, ewday, ewday_offset, skip_interval, temp_buffer[2]) == NULL)
3846 				result = ERROR;
3847 			}
3848 		else if((result = xodtemplate_get_month_from_string(temp_buffer[0], &smon)) == OK && (result = xodtemplate_get_month_from_string(temp_buffer[1], &emon)) == OK) {
3849 			/* february 1 - march 15 / 3 */
3850 			/* add timeperiod exception */
3851 			if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_DATE, 0, smon, smday, 0, 0, 0, emon, emday, 0, 0, skip_interval, temp_buffer[2]) == NULL)
3852 				result = ERROR;
3853 			}
3854 		else if(!strcmp(temp_buffer[0], "day")  && !strcmp(temp_buffer[1], "day")) {
3855 			/* day 4 - 6 / 2 */
3856 			/* add timeperiod exception */
3857 			result = OK;
3858 			if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_DAY, 0, 0, smday, 0, 0, 0, 0, emday, 0, 0, skip_interval, temp_buffer[2]) == NULL)
3859 				result = ERROR;
3860 			}
3861 		}
3862 
3863 	else if((items = sscanf(input, "%[a-z] %d - %d / %d %[0-9:, -]", temp_buffer[0], &smday, &emday, &skip_interval, temp_buffer[1])) == 5) {
3864 		/* february 1 - 15 / 3 */
3865 		/* monday 2 - 3 / 2 */
3866 		/* day 1 - 25 / 4 */
3867 		if((result = xodtemplate_get_weekday_from_string(temp_buffer[0], &swday)) == OK) {
3868 			/* thursday 2 - 4 */
3869 			swday_offset = smday;
3870 			ewday = swday;
3871 			ewday_offset = emday;
3872 			/* add timeperiod exception */
3873 			if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_WEEK_DAY, 0, 0, 0, swday, swday_offset, 0, 0, 0, ewday, ewday_offset, skip_interval, temp_buffer[1]) == NULL)
3874 				result = ERROR;
3875 			}
3876 		else if((result = xodtemplate_get_month_from_string(temp_buffer[0], &smon)) == OK) {
3877 			/* february 3 - 5 */
3878 			emon = smon;
3879 			/* add timeperiod exception */
3880 			if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_DATE, 0, smon, smday, 0, 0, 0, emon, emday, 0, 0, skip_interval, temp_buffer[1]) == NULL)
3881 				result = ERROR;
3882 			}
3883 		else if(!strcmp(temp_buffer[0], "day")) {
3884 			/* day 1 - 4 */
3885 			/* add timeperiod exception */
3886 			result = OK;
3887 			if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_DAY, 0, 0, smday, 0, 0, 0, 0, emday, 0, 0, skip_interval, temp_buffer[1]) == NULL)
3888 				result = ERROR;
3889 			}
3890 		}
3891 
3892 	else if((items = sscanf(input, "%[a-z] %d %[a-z] - %[a-z] %d %[a-z] %[0-9:, -]", temp_buffer[0], &swday_offset, temp_buffer[1], temp_buffer[2], &ewday_offset, temp_buffer[3], temp_buffer[4])) == 7) {
3893 		/* wednesday 1 january - thursday 2 july */
3894 		if((result = xodtemplate_get_weekday_from_string(temp_buffer[0], &swday)) == OK && (result = xodtemplate_get_month_from_string(temp_buffer[1], &smon)) == OK && (result = xodtemplate_get_weekday_from_string(temp_buffer[2], &ewday)) == OK && (result = xodtemplate_get_month_from_string(temp_buffer[3], &emon)) == OK) {
3895 			/* add timeperiod exception */
3896 			if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_WEEK_DAY, 0, smon, 0, swday, swday_offset, 0, emon, 0, ewday, ewday_offset, 0, temp_buffer[4]) == NULL)
3897 				result = ERROR;
3898 			}
3899 		}
3900 
3901 	else if((items = sscanf(input, "%[a-z] %d - %d %[0-9:, -]", temp_buffer[0], &smday, &emday, temp_buffer[1])) == 4) {
3902 		/* february 3 - 5 */
3903 		/* thursday 2 - 4 */
3904 		/* day 1 - 4 */
3905 		if((result = xodtemplate_get_weekday_from_string(temp_buffer[0], &swday)) == OK) {
3906 			/* thursday 2 - 4 */
3907 			swday_offset = smday;
3908 			ewday = swday;
3909 			ewday_offset = emday;
3910 			/* add timeperiod exception */
3911 			if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_WEEK_DAY, 0, 0, 0, swday, swday_offset, 0, 0, 0, ewday, ewday_offset, 0, temp_buffer[1]) == NULL)
3912 				result = ERROR;
3913 			}
3914 		else if((result = xodtemplate_get_month_from_string(temp_buffer[0], &smon)) == OK) {
3915 			/* february 3 - 5 */
3916 			emon = smon;
3917 			/* add timeperiod exception */
3918 			if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_DATE, 0, smon, smday, 0, 0, 0, emon, emday, 0, 0, 0, temp_buffer[1]) == NULL)
3919 				result = ERROR;
3920 			}
3921 		else if(!strcmp(temp_buffer[0], "day")) {
3922 			/* day 1 - 4 */
3923 			/* add timeperiod exception */
3924 			result = OK;
3925 			if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_DAY, 0, 0, smday, 0, 0, 0, 0, emday, 0, 0, 0, temp_buffer[1]) == NULL)
3926 				result = ERROR;
3927 			}
3928 		}
3929 
3930 	else if((items = sscanf(input, "%[a-z] %d - %[a-z] %d %[0-9:, -]", temp_buffer[0], &smday, temp_buffer[1], &emday, temp_buffer[2])) == 5) {
3931 		/* february 1 - march 15 */
3932 		/* monday 2 - thursday 3 */
3933 		/* day 1 - day 5 */
3934 		if((result = xodtemplate_get_weekday_from_string(temp_buffer[0], &swday)) == OK && (result = xodtemplate_get_weekday_from_string(temp_buffer[1], &ewday)) == OK) {
3935 			/* monday 2 - thursday 3 */
3936 			swday_offset = smday;
3937 			ewday_offset = emday;
3938 			/* add timeperiod exception */
3939 			if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_WEEK_DAY, 0, 0, 0, swday, swday_offset, 0, 0, 0, ewday, ewday_offset, 0, temp_buffer[2]) == NULL)
3940 				result = ERROR;
3941 			}
3942 		else if((result = xodtemplate_get_month_from_string(temp_buffer[0], &smon)) == OK && (result = xodtemplate_get_month_from_string(temp_buffer[1], &emon)) == OK) {
3943 			/* february 1 - march 15 */
3944 			/* add timeperiod exception */
3945 			if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_DATE, 0, smon, smday, 0, 0, 0, emon, emday, 0, 0, 0, temp_buffer[2]) == NULL)
3946 				result = ERROR;
3947 			}
3948 		else if(!strcmp(temp_buffer[0], "day")  && !strcmp(temp_buffer[1], "day")) {
3949 			/* day 1 - day 5 */
3950 			/* add timeperiod exception */
3951 			result = OK;
3952 			if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_DAY, 0, 0, smday, 0, 0, 0, 0, emday, 0, 0, 0, temp_buffer[2]) == NULL)
3953 				result = ERROR;
3954 			}
3955 		}
3956 
3957 	else if((items = sscanf(input, "%[a-z] %d%*[ \t]%[0-9:, -]", temp_buffer[0], &smday, temp_buffer[1])) == 3) {
3958 		/* february 3 */
3959 		/* thursday 2 */
3960 		/* day 1 */
3961 		if((result = xodtemplate_get_weekday_from_string(temp_buffer[0], &swday)) == OK) {
3962 			/* thursday 2 */
3963 			swday_offset = smday;
3964 			ewday = swday;
3965 			ewday_offset = swday_offset;
3966 			/* add timeperiod exception */
3967 			if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_WEEK_DAY, 0, 0, 0, swday, swday_offset, 0, 0, 0, ewday, ewday_offset, 0, temp_buffer[1]) == NULL)
3968 				result = ERROR;
3969 			}
3970 		else if((result = xodtemplate_get_month_from_string(temp_buffer[0], &smon)) == OK) {
3971 			/* february 3 */
3972 			emon = smon;
3973 			emday = smday;
3974 			/* add timeperiod exception */
3975 			if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_DATE, 0, smon, smday, 0, 0, 0, emon, emday, 0, 0, 0, temp_buffer[1]) == NULL)
3976 				result = ERROR;
3977 			}
3978 		else if(!strcmp(temp_buffer[0], "day")) {
3979 			/* day 1 */
3980 			emday = smday;
3981 			/* add timeperiod exception */
3982 			result = OK;
3983 			if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_DAY, 0, 0, smday, 0, 0, 0, 0, emday, 0, 0, 0, temp_buffer[1]) == NULL)
3984 				result = ERROR;
3985 			}
3986 		}
3987 
3988 	else if((items = sscanf(input, "%[a-z] %d %[a-z] %[0-9:, -]", temp_buffer[0], &swday_offset, temp_buffer[1], temp_buffer[2])) == 4) {
3989 		/* thursday 3 february */
3990 		if((result = xodtemplate_get_weekday_from_string(temp_buffer[0], &swday)) == OK && (result = xodtemplate_get_month_from_string(temp_buffer[1], &smon)) == OK) {
3991 			emon = smon;
3992 			ewday = swday;
3993 			ewday_offset = swday_offset;
3994 			/* add timeperiod exception */
3995 			if(xodtemplate_add_exception_to_timeperiod(tperiod, DATERANGE_MONTH_WEEK_DAY, 0, smon, 0, swday, swday_offset, 0, emon, 0, ewday, ewday_offset, 0, temp_buffer[2]) == NULL)
3996 				result = ERROR;
3997 			}
3998 		}
3999 
4000 	else if((items = sscanf(input, "%[a-z] %[0-9:, -]", temp_buffer[0], temp_buffer[1])) == 2) {
4001 		/* monday */
4002 		if((result = xodtemplate_get_weekday_from_string(temp_buffer[0], &swday)) == OK) {
4003 			/* add normal weekday timerange */
4004 			if((tperiod->timeranges[swday] = (char *)strdup(temp_buffer[1])) == NULL)
4005 				result = ERROR;
4006 			}
4007 		}
4008 
4009 	else
4010 		result = ERROR;
4011 
4012 #ifdef NSCORE
4013 	if(result == ERROR) {
4014 		printf("Error: Could not parse timeperiod directive '%s'!\n", input);
4015 		}
4016 #endif
4017 
4018 	/* free memory */
4019 	my_free(input);
4020 
4021 	return result;
4022 	}
4023 
4024 
4025 
4026 /* add a new exception to a timeperiod */
xodtemplate_add_exception_to_timeperiod(xodtemplate_timeperiod * period,int type,int syear,int smon,int smday,int swday,int swday_offset,int eyear,int emon,int emday,int ewday,int ewday_offset,int skip_interval,char * timeranges)4027 xodtemplate_daterange *xodtemplate_add_exception_to_timeperiod(xodtemplate_timeperiod *period, int type, int syear, int smon, int smday, int swday, int swday_offset, int eyear, int emon, int emday, int ewday, int ewday_offset, int skip_interval, char *timeranges) {
4028 	xodtemplate_daterange *new_daterange = NULL;
4029 
4030 	/* make sure we have the data we need */
4031 	if(period == NULL || timeranges == NULL)
4032 		return NULL;
4033 
4034 	/* allocate memory for the date range range */
4035 	if((new_daterange = malloc(sizeof(xodtemplate_daterange))) == NULL)
4036 		return NULL;
4037 
4038 	new_daterange->next = NULL;
4039 
4040 	new_daterange->type = type;
4041 	new_daterange->syear = syear;
4042 	new_daterange->smon = smon;
4043 	new_daterange->smday = smday;
4044 	new_daterange->swday = swday;
4045 	new_daterange->swday_offset = swday_offset;
4046 	new_daterange->eyear = eyear;
4047 	new_daterange->emon = emon;
4048 	new_daterange->emday = emday;
4049 	new_daterange->ewday = ewday;
4050 	new_daterange->ewday_offset = ewday_offset;
4051 	new_daterange->skip_interval = skip_interval;
4052 	new_daterange->timeranges = (char *)strdup(timeranges);
4053 
4054 	/* add the new date range to the head of the range list for this exception type */
4055 	new_daterange->next = period->exceptions[type];
4056 	period->exceptions[type] = new_daterange;
4057 
4058 	return new_daterange;
4059 	}
4060 
4061 
4062 
xodtemplate_get_month_from_string(char * str,int * month)4063 int xodtemplate_get_month_from_string(char *str, int *month) {
4064 	char *months[12] = {"january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"};
4065 	int x = 0;
4066 
4067 	if(str == NULL || month == NULL)
4068 		return ERROR;
4069 
4070 	for(x = 0; x < 12; x++) {
4071 		if(!strcmp(str, months[x])) {
4072 			*month = x;
4073 			return OK;
4074 			}
4075 		}
4076 
4077 	return ERROR;
4078 	}
4079 
4080 
4081 
4082 
xodtemplate_get_weekday_from_string(char * str,int * weekday)4083 int xodtemplate_get_weekday_from_string(char *str, int *weekday) {
4084 	char *days[7] = {"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"};
4085 	int x = 0;
4086 
4087 	if(str == NULL || weekday == NULL)
4088 		return ERROR;
4089 
4090 	for(x = 0; x < 7; x++) {
4091 		if(!strcmp(str, days[x])) {
4092 			*weekday = x;
4093 			return OK;
4094 			}
4095 		}
4096 
4097 	return ERROR;
4098 	}
4099 
4100 
4101 
4102 /******************************************************************/
4103 /***************** OBJECT DUPLICATION FUNCTIONS *******************/
4104 /******************************************************************/
4105 
4106 #ifdef NSCORE
4107 
4108 /* duplicates service definitions */
xodtemplate_duplicate_services(void)4109 int xodtemplate_duplicate_services(void) {
4110 	int result = OK;
4111 	xodtemplate_service *temp_service = NULL;
4112 	xodtemplate_memberlist *temp_memberlist = NULL;
4113 	xodtemplate_memberlist *temp_rejectlist = NULL;
4114 	xodtemplate_memberlist *this_memberlist = NULL;
4115 	char *host_name = NULL;
4116 	int first_item = FALSE;
4117 
4118 
4119 	/****** DUPLICATE SERVICE DEFINITIONS WITH ONE OR MORE HOSTGROUP AND/OR HOST NAMES ******/
4120 	for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) {
4121 
4122 		/* skip service definitions without enough data */
4123 		if(temp_service->hostgroup_name == NULL && temp_service->host_name == NULL)
4124 			continue;
4125 
4126 		/* If hostgroup is not null and hostgroup has no members, check to see if */
4127 		/* allow_empty_hostgroup_assignment is set to 1 - if it is, continue without error  */
4128 		if(temp_service->hostgroup_name != NULL) {
4129 			if(xodtemplate_expand_hostgroups(&temp_memberlist, &temp_rejectlist, temp_service->hostgroup_name, temp_service->_config_file, temp_service->_start_line) == ERROR) {
4130 				return ERROR;
4131 				}
4132 			else {
4133 				xodtemplate_free_memberlist(&temp_rejectlist);
4134 				if(temp_memberlist != NULL) {
4135 					xodtemplate_free_memberlist(&temp_memberlist);
4136 					}
4137 				else {
4138 					/* User is ok with hostgroup -> service mappings with no hosts */
4139 					if(allow_empty_hostgroup_assignment == 1) {
4140 						continue;
4141 						}
4142 					}
4143 				}
4144 			}
4145 
4146 		/* skip services that shouldn't be registered */
4147 		if(temp_service->register_object == FALSE)
4148 			continue;
4149 
4150 		/* get list of hosts */
4151 		temp_memberlist = xodtemplate_expand_hostgroups_and_hosts(temp_service->hostgroup_name, temp_service->host_name, temp_service->_config_file, temp_service->_start_line);
4152 		if(temp_memberlist == NULL) {
4153 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand hostgroups and/or hosts specified in service (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_service->_config_file), temp_service->_start_line);
4154 			return ERROR;
4155 			}
4156 
4157 		/* add a copy of the service for every host in the hostgroup/host name list */
4158 		first_item = TRUE;
4159 		for(this_memberlist = temp_memberlist; this_memberlist != NULL; this_memberlist = this_memberlist->next) {
4160 
4161 			/* if this is the first duplication, use the existing entry */
4162 			if(first_item == TRUE) {
4163 
4164 				my_free(temp_service->host_name);
4165 				temp_service->host_name = (char *)strdup(this_memberlist->name1);
4166 				if(temp_service->host_name == NULL) {
4167 					xodtemplate_free_memberlist(&temp_memberlist);
4168 					return ERROR;
4169 					}
4170 
4171 				first_item = FALSE;
4172 				continue;
4173 				}
4174 
4175 			/* duplicate service definition */
4176 			result = xodtemplate_duplicate_service(temp_service, this_memberlist->name1);
4177 
4178 			/* exit on error */
4179 			if(result == ERROR) {
4180 				my_free(host_name);
4181 				return ERROR;
4182 				}
4183 			}
4184 
4185 		/* free memory we used for host list */
4186 		xodtemplate_free_memberlist(&temp_memberlist);
4187 		}
4188 
4189 
4190 	/***************************************/
4191 	/* SKIPLIST STUFF FOR FAST SORT/SEARCH */
4192 	/***************************************/
4193 
4194 	/* First loop for single host service definition*/
4195 	for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) {
4196 
4197 		/* skip services that shouldn't be registered */
4198 		if(temp_service->register_object == FALSE)
4199 			continue;
4200 
4201 		/* skip service definitions without enough data */
4202 		if(temp_service->host_name == NULL || temp_service->service_description == NULL)
4203 			continue;
4204 
4205 		if(xodtemplate_is_service_is_from_hostgroup(temp_service)) {
4206 			continue;
4207 			}
4208 
4209 
4210 		result = skiplist_insert(xobject_skiplists[X_SERVICE_SKIPLIST], (void *)temp_service);
4211 		switch(result) {
4212 			case SKIPLIST_ERROR_DUPLICATE:
4213 				logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for service '%s' on host '%s' (config file '%s', starting on line %d)\n", temp_service->service_description, temp_service->host_name, xodtemplate_config_file_name(temp_service->_config_file), temp_service->_start_line);
4214 				result = ERROR;
4215 				break;
4216 			case SKIPLIST_OK:
4217 				result = OK;
4218 				break;
4219 			default:
4220 				result = ERROR;
4221 				break;
4222 			}
4223 		}
4224 
4225 
4226 	/* second loop for host group service definition*/
4227 	/* add services to skiplist for fast searches */
4228 	for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) {
4229 
4230 		/* skip services that shouldn't be registered */
4231 		if(temp_service->register_object == FALSE)
4232 			continue;
4233 
4234 		/* skip service definitions without enough data */
4235 		if(temp_service->host_name == NULL || temp_service->service_description == NULL)
4236 			continue;
4237 
4238 		if(!xodtemplate_is_service_is_from_hostgroup(temp_service)) {
4239 			continue;
4240 			}
4241 		/*The flag X_SERVICE_IS_FROM_HOSTGROUP is set, unset it*/
4242 		xodtemplate_unset_service_is_from_hostgroup(temp_service);
4243 
4244 		result = skiplist_insert(xobject_skiplists[X_SERVICE_SKIPLIST], (void *)temp_service);
4245 		switch(result) {
4246 			case SKIPLIST_ERROR_DUPLICATE:
4247 				logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Duplicate definition found for service '%s' on host '%s' (config file '%s', starting on line %d)\n", temp_service->service_description, temp_service->host_name, xodtemplate_config_file_name(temp_service->_config_file), temp_service->_start_line);
4248 				result = ERROR;
4249 				break;
4250 			case SKIPLIST_OK:
4251 				result = OK;
4252 				break;
4253 			default:
4254 				result = ERROR;
4255 				break;
4256 			}
4257 		}
4258 
4259 	return OK;
4260 	}
4261 
4262 
4263 
4264 /* duplicates object definitions */
xodtemplate_duplicate_objects(void)4265 int xodtemplate_duplicate_objects(void) {
4266 	int result = OK;
4267 	xodtemplate_hostescalation *temp_hostescalation = NULL;
4268 	xodtemplate_serviceescalation *temp_serviceescalation = NULL;
4269 	xodtemplate_hostdependency *temp_hostdependency = NULL;
4270 	xodtemplate_servicedependency *temp_servicedependency = NULL;
4271 	xodtemplate_hostextinfo *temp_hostextinfo = NULL;
4272 	xodtemplate_serviceextinfo *temp_serviceextinfo = NULL;
4273 
4274 	xodtemplate_memberlist *master_hostlist = NULL, *dependent_hostlist = NULL;
4275 	xodtemplate_memberlist *master_servicelist = NULL, *dependent_servicelist = NULL;
4276 	xodtemplate_memberlist *temp_masterhost = NULL, *temp_dependenthost = NULL;
4277 	xodtemplate_memberlist *temp_masterservice = NULL, *temp_dependentservice = NULL;
4278 
4279 	char *service_descriptions = NULL;
4280 	int first_item = FALSE;
4281 	int same_host_servicedependency = FALSE;
4282 
4283 
4284 	/*************************************/
4285 	/* SERVICES ARE DUPLICATED ELSEWHERE */
4286 	/*************************************/
4287 
4288 
4289 	/****** DUPLICATE HOST ESCALATION DEFINITIONS WITH ONE OR MORE HOSTGROUP AND/OR HOST NAMES ******/
4290 	for(temp_hostescalation = xodtemplate_hostescalation_list; temp_hostescalation != NULL; temp_hostescalation = temp_hostescalation->next) {
4291 
4292 		/* skip host escalation definitions without enough data */
4293 		if(temp_hostescalation->hostgroup_name == NULL && temp_hostescalation->host_name == NULL)
4294 			continue;
4295 
4296 		/* get list of hosts */
4297 		master_hostlist = xodtemplate_expand_hostgroups_and_hosts(temp_hostescalation->hostgroup_name, temp_hostescalation->host_name, temp_hostescalation->_config_file, temp_hostescalation->_start_line);
4298 		if(master_hostlist == NULL) {
4299 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand hostgroups and/or hosts specified in host escalation (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_hostescalation->_config_file), temp_hostescalation->_start_line);
4300 			return ERROR;
4301 			}
4302 
4303 		/* add a copy of the hostescalation for every host in the hostgroup/host name list */
4304 		first_item = TRUE;
4305 		for(temp_masterhost = master_hostlist; temp_masterhost != NULL; temp_masterhost = temp_masterhost->next) {
4306 
4307 			/* if this is the first duplication, use the existing entry */
4308 			if(first_item == TRUE) {
4309 
4310 				my_free(temp_hostescalation->host_name);
4311 				temp_hostescalation->host_name = (char *)strdup(temp_masterhost->name1);
4312 				if(temp_hostescalation->host_name == NULL) {
4313 					xodtemplate_free_memberlist(&master_hostlist);
4314 					return ERROR;
4315 					}
4316 
4317 				first_item = FALSE;
4318 				continue;
4319 				}
4320 
4321 			/* duplicate hostescalation definition */
4322 			result = xodtemplate_duplicate_hostescalation(temp_hostescalation, temp_masterhost->name1);
4323 
4324 			/* exit on error */
4325 			if(result == ERROR) {
4326 				xodtemplate_free_memberlist(&master_hostlist);
4327 				return ERROR;
4328 				}
4329 			}
4330 
4331 		/* free memory we used for host list */
4332 		xodtemplate_free_memberlist(&master_hostlist);
4333 		}
4334 
4335 
4336 	/****** DUPLICATE SERVICE ESCALATION DEFINITIONS WITH ONE OR MORE HOSTGROUP AND/OR HOST NAMES ******/
4337 	for(temp_serviceescalation = xodtemplate_serviceescalation_list; temp_serviceescalation != NULL; temp_serviceescalation = temp_serviceescalation->next) {
4338 
4339 		/* skip service escalation definitions without enough data */
4340 		if(temp_serviceescalation->hostgroup_name == NULL && temp_serviceescalation->host_name == NULL)
4341 			continue;
4342 
4343 		/* get list of hosts */
4344 		master_hostlist = xodtemplate_expand_hostgroups_and_hosts(temp_serviceescalation->hostgroup_name, temp_serviceescalation->host_name, temp_serviceescalation->_config_file, temp_serviceescalation->_start_line);
4345 		if(master_hostlist == NULL) {
4346 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand hostgroups and/or hosts specified in service escalation (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_serviceescalation->_config_file), temp_serviceescalation->_start_line);
4347 			return ERROR;
4348 			}
4349 
4350 		/* duplicate service escalation entries */
4351 		first_item = TRUE;
4352 		for(temp_masterhost = master_hostlist; temp_masterhost != NULL; temp_masterhost = temp_masterhost->next) {
4353 
4354 			/* if this is the first duplication,use the existing entry */
4355 			if(first_item == TRUE) {
4356 
4357 				my_free(temp_serviceescalation->host_name);
4358 				temp_serviceescalation->host_name = (char *)strdup(temp_masterhost->name1);
4359 				if(temp_serviceescalation->host_name == NULL) {
4360 					xodtemplate_free_memberlist(&master_hostlist);
4361 					return ERROR;
4362 					}
4363 
4364 				first_item = FALSE;
4365 				continue;
4366 				}
4367 
4368 			/* duplicate service escalation definition */
4369 			result = xodtemplate_duplicate_serviceescalation(temp_serviceescalation, temp_masterhost->name1, temp_serviceescalation->service_description);
4370 
4371 			/* exit on error */
4372 			if(result == ERROR) {
4373 				xodtemplate_free_memberlist(&master_hostlist);
4374 				return ERROR;
4375 				}
4376 			}
4377 
4378 		/* free memory we used for host list */
4379 		xodtemplate_free_memberlist(&master_hostlist);
4380 		}
4381 
4382 
4383 	/****** DUPLICATE SERVICE ESCALATION DEFINITIONS WITH MULTIPLE DESCRIPTIONS ******/
4384 	/* THIS MUST BE DONE AFTER DUPLICATING FOR MULTIPLE HOST NAMES (SEE ABOVE) */
4385 	for(temp_serviceescalation = xodtemplate_serviceescalation_list; temp_serviceescalation != NULL; temp_serviceescalation = temp_serviceescalation->next) {
4386 
4387 		/* skip serviceescalations without enough data */
4388 		if(temp_serviceescalation->service_description == NULL || temp_serviceescalation->host_name == NULL)
4389 			continue;
4390 
4391 		/* get list of services */
4392 		master_servicelist = xodtemplate_expand_servicegroups_and_services(NULL, temp_serviceescalation->host_name, temp_serviceescalation->service_description, temp_serviceescalation->_config_file, temp_serviceescalation->_start_line);
4393 		if(master_servicelist == NULL) {
4394 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand services specified in service escalation (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_serviceescalation->_config_file), temp_serviceescalation->_start_line);
4395 			return ERROR;
4396 			}
4397 
4398 		/* duplicate service escalation entries */
4399 		first_item = TRUE;
4400 		for(temp_masterservice = master_servicelist; temp_masterservice != NULL; temp_masterservice = temp_masterservice->next) {
4401 
4402 			/* if this is the first duplication, use the existing entry */
4403 			if(first_item == TRUE) {
4404 
4405 				my_free(temp_serviceescalation->service_description);
4406 				temp_serviceescalation->service_description = (char *)strdup(temp_masterservice->name2);
4407 				if(temp_serviceescalation->service_description == NULL) {
4408 					xodtemplate_free_memberlist(&master_servicelist);
4409 					return ERROR;
4410 					}
4411 
4412 				first_item = FALSE;
4413 				continue;
4414 				}
4415 
4416 			/* duplicate service escalation definition */
4417 			result = xodtemplate_duplicate_serviceescalation(temp_serviceescalation, temp_serviceescalation->host_name, temp_masterservice->name2);
4418 
4419 			/* exit on error */
4420 			if(result == ERROR) {
4421 				xodtemplate_free_memberlist(&master_servicelist);
4422 				return ERROR;
4423 				}
4424 			}
4425 
4426 		/* free memory we used for service list */
4427 		xodtemplate_free_memberlist(&master_servicelist);
4428 		}
4429 
4430 
4431 
4432 	/****** DUPLICATE SERVICE ESCALATION DEFINITIONS WITH SERVICEGROUPS ******/
4433 	/* THIS MUST BE DONE AFTER DUPLICATING FOR MULTIPLE HOST NAMES (SEE ABOVE) */
4434 	for(temp_serviceescalation = xodtemplate_serviceescalation_list; temp_serviceescalation != NULL; temp_serviceescalation = temp_serviceescalation->next) {
4435 
4436 		/* skip serviceescalations without enough data */
4437 		if(temp_serviceescalation->servicegroup_name == NULL)
4438 			continue;
4439 
4440 		/* get list of services */
4441 		master_servicelist = xodtemplate_expand_servicegroups_and_services(temp_serviceescalation->servicegroup_name, NULL, NULL, temp_serviceescalation->_config_file, temp_serviceescalation->_start_line);
4442 		if(master_servicelist == NULL) {
4443 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand servicegroups specified in service escalation (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_serviceescalation->_config_file), temp_serviceescalation->_start_line);
4444 			return ERROR;
4445 			}
4446 
4447 		/* duplicate service escalation entries */
4448 		first_item = TRUE;
4449 		for(temp_masterservice = master_servicelist; temp_masterservice != NULL; temp_masterservice = temp_masterservice->next) {
4450 
4451 			/* if this is the first duplication, use the existing entry if possible */
4452 			if(first_item == TRUE && temp_serviceescalation->host_name == NULL && temp_serviceescalation->service_description == NULL) {
4453 
4454 				my_free(temp_serviceescalation->host_name);
4455 				temp_serviceescalation->host_name = (char *)strdup(temp_masterservice->name1);
4456 
4457 				my_free(temp_serviceescalation->service_description);
4458 				temp_serviceescalation->service_description = (char *)strdup(temp_masterservice->name2);
4459 
4460 				if(temp_serviceescalation->host_name == NULL || temp_serviceescalation->service_description == NULL) {
4461 					xodtemplate_free_memberlist(&master_servicelist);
4462 					return ERROR;
4463 					}
4464 
4465 				first_item = FALSE;
4466 				continue;
4467 				}
4468 
4469 			/* duplicate service escalation definition */
4470 			result = xodtemplate_duplicate_serviceescalation(temp_serviceescalation, temp_masterservice->name1, temp_masterservice->name2);
4471 
4472 			/* exit on error */
4473 			if(result == ERROR) {
4474 				xodtemplate_free_memberlist(&master_servicelist);
4475 				return ERROR;
4476 				}
4477 			}
4478 
4479 		/* free memory we used for service list */
4480 		xodtemplate_free_memberlist(&master_servicelist);
4481 		}
4482 
4483 
4484 	/****** DUPLICATE HOST DEPENDENCY DEFINITIONS WITH MULTIPLE HOSTGROUP AND/OR HOST NAMES (MASTER AND DEPENDENT) ******/
4485 	for(temp_hostdependency = xodtemplate_hostdependency_list; temp_hostdependency != NULL; temp_hostdependency = temp_hostdependency->next) {
4486 
4487 		/* skip host dependencies without enough data */
4488 		if(temp_hostdependency->hostgroup_name == NULL && temp_hostdependency->dependent_hostgroup_name == NULL && temp_hostdependency->host_name == NULL && temp_hostdependency->dependent_host_name == NULL)
4489 			continue;
4490 
4491 		/* get list of master host names */
4492 		master_hostlist = xodtemplate_expand_hostgroups_and_hosts(temp_hostdependency->hostgroup_name, temp_hostdependency->host_name, temp_hostdependency->_config_file, temp_hostdependency->_start_line);
4493 		if(master_hostlist == NULL && allow_empty_hostgroup_assignment == 0) {
4494 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand master hostgroups and/or hosts specified in host dependency (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_hostdependency->_config_file), temp_hostdependency->_start_line);
4495 			return ERROR;
4496 			}
4497 
4498 		/* get list of dependent host names */
4499 		dependent_hostlist = xodtemplate_expand_hostgroups_and_hosts(temp_hostdependency->dependent_hostgroup_name, temp_hostdependency->dependent_host_name, temp_hostdependency->_config_file, temp_hostdependency->_start_line);
4500 		if(dependent_hostlist == NULL && allow_empty_hostgroup_assignment == 0) {
4501 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand dependent hostgroups and/or hosts specified in host dependency (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_hostdependency->_config_file), temp_hostdependency->_start_line);
4502 			xodtemplate_free_memberlist(&master_hostlist);
4503 			return ERROR;
4504 			}
4505 
4506 		/* duplicate the dependency definitions */
4507 		first_item = TRUE;
4508 		for(temp_masterhost = master_hostlist; temp_masterhost != NULL; temp_masterhost = temp_masterhost->next) {
4509 
4510 			for(temp_dependenthost = dependent_hostlist; temp_dependenthost != NULL; temp_dependenthost = temp_dependenthost->next) {
4511 
4512 				/* temp=master, this=dep */
4513 
4514 				/* existing definition gets first names */
4515 				if(first_item == TRUE) {
4516 					my_free(temp_hostdependency->host_name);
4517 					my_free(temp_hostdependency->dependent_host_name);
4518 					temp_hostdependency->host_name = (char *)strdup(temp_masterhost->name1);
4519 					temp_hostdependency->dependent_host_name = (char *)strdup(temp_dependenthost->name1);
4520 					first_item = FALSE;
4521 					continue;
4522 					}
4523 				else
4524 					result = xodtemplate_duplicate_hostdependency(temp_hostdependency, temp_masterhost->name1, temp_dependenthost->name1);
4525 				/* exit on error */
4526 				if(result == ERROR) {
4527 					xodtemplate_free_memberlist(&master_hostlist);
4528 					xodtemplate_free_memberlist(&dependent_hostlist);
4529 					return ERROR;
4530 					}
4531 				}
4532 			}
4533 
4534 		/* free memory used to store host lists */
4535 		xodtemplate_free_memberlist(&master_hostlist);
4536 		xodtemplate_free_memberlist(&dependent_hostlist);
4537 		}
4538 
4539 
4540 
4541 	/****** PROCESS SERVICE DEPENDENCIES WITH MASTER SERVICEGROUPS *****/
4542 	for(temp_servicedependency = xodtemplate_servicedependency_list; temp_servicedependency != NULL; temp_servicedependency = temp_servicedependency->next) {
4543 
4544 		/* skip templates */
4545 		if(temp_servicedependency->register_object == 0)
4546 			continue;
4547 
4548 		/* expand master servicegroups into a list of services */
4549 		if(temp_servicedependency->servicegroup_name) {
4550 
4551 			master_servicelist = xodtemplate_expand_servicegroups_and_services(temp_servicedependency->servicegroup_name, NULL, NULL, temp_servicedependency->_config_file, temp_servicedependency->_start_line);
4552 			if(master_servicelist == NULL) {
4553 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand master servicegroups specified in service dependency (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_servicedependency->_config_file), temp_servicedependency->_start_line);
4554 				return ERROR;
4555 				}
4556 
4557 			/* if dependency also has master host, hostgroup, and/or service, we must split that off to another definition */
4558 			if(temp_servicedependency->host_name != NULL || temp_servicedependency->hostgroup_name != NULL || temp_servicedependency->service_description != NULL) {
4559 
4560 				/* duplicate everything except master servicegroup */
4561 				xodtemplate_duplicate_servicedependency(temp_servicedependency, temp_servicedependency->host_name, temp_servicedependency->service_description, temp_servicedependency->hostgroup_name, NULL, temp_servicedependency->dependent_host_name, temp_servicedependency->dependent_service_description, temp_servicedependency->dependent_hostgroup_name, temp_servicedependency->dependent_servicegroup_name);
4562 
4563 				/* clear values in this definition */
4564 				temp_servicedependency->have_host_name = FALSE;
4565 				temp_servicedependency->have_service_description = FALSE;
4566 				temp_servicedependency->have_hostgroup_name = FALSE;
4567 				my_free(temp_servicedependency->host_name);
4568 				my_free(temp_servicedependency->service_description);
4569 				my_free(temp_servicedependency->hostgroup_name);
4570 				}
4571 
4572 			/* duplicate service dependency entries */
4573 			first_item = TRUE;
4574 			for(temp_masterservice = master_servicelist; temp_masterservice != NULL; temp_masterservice = temp_masterservice->next) {
4575 
4576 				/* just in case */
4577 				if(temp_masterservice->name1 == NULL || temp_masterservice->name2 == NULL)
4578 					continue;
4579 
4580 				/* if this is the first duplication, use the existing entry */
4581 				if(first_item == TRUE) {
4582 
4583 					my_free(temp_servicedependency->host_name);
4584 					temp_servicedependency->host_name = (char *)strdup(temp_masterservice->name1);
4585 
4586 					my_free(temp_servicedependency->service_description);
4587 					temp_servicedependency->service_description = (char *)strdup(temp_masterservice->name2);
4588 
4589 					/* clear the master servicegroup */
4590 					temp_servicedependency->have_servicegroup_name = FALSE;
4591 					my_free(temp_servicedependency->servicegroup_name);
4592 
4593 					if(temp_servicedependency->host_name == NULL || temp_servicedependency->service_description == NULL) {
4594 						xodtemplate_free_memberlist(&master_servicelist);
4595 						return ERROR;
4596 						}
4597 
4598 					first_item = FALSE;
4599 					continue;
4600 					}
4601 
4602 				/* duplicate service dependency definition */
4603 				result = xodtemplate_duplicate_servicedependency(temp_servicedependency, temp_masterservice->name1, temp_masterservice->name2, NULL, NULL, temp_servicedependency->dependent_host_name, temp_servicedependency->dependent_service_description, temp_servicedependency->dependent_hostgroup_name, temp_servicedependency->dependent_servicegroup_name);
4604 
4605 				/* exit on error */
4606 				if(result == ERROR) {
4607 					xodtemplate_free_memberlist(&master_servicelist);
4608 					return ERROR;
4609 					}
4610 				}
4611 
4612 			/* free memory we used for service list */
4613 			xodtemplate_free_memberlist(&master_servicelist);
4614 			}
4615 		}
4616 
4617 
4618 	/****** PROCESS SERVICE DEPENDENCY MASTER HOSTS/HOSTGROUPS/SERVICES *****/
4619 	for(temp_servicedependency = xodtemplate_servicedependency_list; temp_servicedependency != NULL; temp_servicedependency = temp_servicedependency->next) {
4620 
4621 		/* skip templates */
4622 		if(temp_servicedependency->register_object == 0)
4623 			continue;
4624 
4625 		/* expand master hosts/hostgroups into a list of host names */
4626 		if(temp_servicedependency->host_name != NULL || temp_servicedependency->hostgroup_name != NULL) {
4627 
4628 #ifdef DEBUG_SERVICE_DEPENDENCIES
4629 			printf("1a) H: %s  HG: %s  SD: %s\n", temp_servicedependency->host_name, temp_servicedependency->hostgroup_name, temp_servicedependency->service_description);
4630 #endif
4631 
4632 			master_hostlist = xodtemplate_expand_hostgroups_and_hosts(temp_servicedependency->hostgroup_name, temp_servicedependency->host_name, temp_servicedependency->_config_file, temp_servicedependency->_start_line);
4633 			if(master_hostlist == NULL && allow_empty_hostgroup_assignment == 0) {
4634 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand master hostgroups and/or hosts specified in service dependency (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_servicedependency->_config_file), temp_servicedependency->_start_line);
4635 				return ERROR;
4636 				}
4637 
4638 			/* save service descriptions for later */
4639 			if(temp_servicedependency->service_description)
4640 				service_descriptions = (char *)strdup(temp_servicedependency->service_description);
4641 
4642 			/* for each host, expand master services */
4643 			first_item = TRUE;
4644 			for(temp_masterhost = master_hostlist; temp_masterhost != NULL; temp_masterhost = temp_masterhost->next) {
4645 
4646 				master_servicelist = xodtemplate_expand_servicegroups_and_services(NULL, temp_masterhost->name1, service_descriptions, temp_servicedependency->_config_file, temp_servicedependency->_start_line);
4647 				if(master_servicelist == NULL) {
4648 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand master services specified in service dependency (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_servicedependency->_config_file), temp_servicedependency->_start_line);
4649 					return ERROR;
4650 					}
4651 
4652 				/* duplicate service dependency entries */
4653 				for(temp_masterservice = master_servicelist; temp_masterservice != NULL; temp_masterservice = temp_masterservice->next) {
4654 
4655 					/* just in case */
4656 					if(temp_masterservice->name1 == NULL || temp_masterservice->name2 == NULL)
4657 						continue;
4658 
4659 					/* if this is the first duplication, use the existing entry */
4660 					if(first_item == TRUE) {
4661 
4662 						my_free(temp_servicedependency->host_name);
4663 						temp_servicedependency->host_name = (char *)strdup(temp_masterhost->name1);
4664 
4665 						my_free(temp_servicedependency->service_description);
4666 						temp_servicedependency->service_description = (char *)strdup(temp_masterservice->name2);
4667 
4668 						if(temp_servicedependency->host_name == NULL || temp_servicedependency->service_description == NULL) {
4669 							xodtemplate_free_memberlist(&master_hostlist);
4670 							xodtemplate_free_memberlist(&master_servicelist);
4671 							return ERROR;
4672 							}
4673 
4674 						first_item = FALSE;
4675 						continue;
4676 						}
4677 
4678 					/* duplicate service dependency definition */
4679 					result = xodtemplate_duplicate_servicedependency(temp_servicedependency, temp_masterhost->name1, temp_masterservice->name2, NULL, NULL, temp_servicedependency->dependent_host_name, temp_servicedependency->dependent_service_description, temp_servicedependency->dependent_hostgroup_name, temp_servicedependency->dependent_servicegroup_name);
4680 
4681 					/* exit on error */
4682 					if(result == ERROR) {
4683 						xodtemplate_free_memberlist(&master_hostlist);
4684 						xodtemplate_free_memberlist(&master_servicelist);
4685 						return ERROR;
4686 						}
4687 					}
4688 
4689 				/* free memory we used for service list */
4690 				xodtemplate_free_memberlist(&master_servicelist);
4691 				}
4692 
4693 			/* free service descriptions */
4694 			my_free(service_descriptions);
4695 
4696 			/* free memory we used for host list */
4697 			xodtemplate_free_memberlist(&master_hostlist);
4698 			}
4699 		}
4700 
4701 
4702 #ifdef DEBUG_SERVICE_DEPENDENCIES
4703 	for(temp_servicedependency = xodtemplate_servicedependency_list; temp_servicedependency != NULL; temp_servicedependency = temp_servicedependency->next) {
4704 		printf("1**) H: %s  HG: %s  SG: %s  SD: %s  DH: %s  DHG: %s  DSG: %s  DSD: %s\n", temp_servicedependency->host_name, temp_servicedependency->hostgroup_name, temp_servicedependency->servicegroup_name, temp_servicedependency->service_description, temp_servicedependency->dependent_host_name, temp_servicedependency->dependent_hostgroup_name, temp_servicedependency->dependent_servicegroup_name, temp_servicedependency->dependent_service_description);
4705 		}
4706 	printf("\n");
4707 #endif
4708 
4709 
4710 	/****** PROCESS SERVICE DEPENDENCIES WITH DEPENDENT SERVICEGROUPS *****/
4711 	for(temp_servicedependency = xodtemplate_servicedependency_list; temp_servicedependency != NULL; temp_servicedependency = temp_servicedependency->next) {
4712 
4713 		/* skip templates */
4714 		if(temp_servicedependency->register_object == 0)
4715 			continue;
4716 
4717 		/* expand dependent servicegroups into a list of services */
4718 		if(temp_servicedependency->dependent_servicegroup_name) {
4719 
4720 			dependent_servicelist = xodtemplate_expand_servicegroups_and_services(temp_servicedependency->dependent_servicegroup_name, NULL, NULL, temp_servicedependency->_config_file, temp_servicedependency->_start_line);
4721 			if(dependent_servicelist == NULL) {
4722 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand dependent servicegroups specified in service dependency (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_servicedependency->_config_file), temp_servicedependency->_start_line);
4723 				return ERROR;
4724 				}
4725 
4726 			/* if dependency also has dependent host, hostgroup, and/or service, we must split that off to another definition */
4727 			if(temp_servicedependency->dependent_host_name != NULL || temp_servicedependency->dependent_hostgroup_name != NULL || temp_servicedependency->dependent_service_description != NULL) {
4728 
4729 				/* duplicate everything except dependent servicegroup */
4730 				xodtemplate_duplicate_servicedependency(temp_servicedependency, temp_servicedependency->host_name, temp_servicedependency->service_description, temp_servicedependency->hostgroup_name, temp_servicedependency->servicegroup_name, temp_servicedependency->dependent_host_name, temp_servicedependency->dependent_service_description, temp_servicedependency->dependent_hostgroup_name, NULL);
4731 
4732 				/* clear values in this definition */
4733 				temp_servicedependency->have_dependent_host_name = FALSE;
4734 				temp_servicedependency->have_dependent_service_description = FALSE;
4735 				temp_servicedependency->have_dependent_hostgroup_name = FALSE;
4736 				my_free(temp_servicedependency->dependent_host_name);
4737 				my_free(temp_servicedependency->dependent_service_description);
4738 				my_free(temp_servicedependency->dependent_hostgroup_name);
4739 				}
4740 
4741 			/* Detected same host servicegroups dependencies */
4742 			same_host_servicedependency = FALSE;
4743 			if(temp_servicedependency->host_name == NULL && temp_servicedependency->hostgroup_name == NULL)
4744 				same_host_servicedependency = TRUE;
4745 
4746 			/* duplicate service dependency entries */
4747 			first_item = TRUE;
4748 			for(temp_dependentservice = dependent_servicelist; temp_dependentservice != NULL; temp_dependentservice = temp_dependentservice->next) {
4749 
4750 				/* just in case */
4751 				if(temp_dependentservice->name1 == NULL || temp_dependentservice->name2 == NULL)
4752 					continue;
4753 
4754 				/* if this is the first duplication, use the existing entry */
4755 				if(first_item == TRUE) {
4756 
4757 					my_free(temp_servicedependency->dependent_host_name);
4758 					temp_servicedependency->dependent_host_name = (char *)strdup(temp_dependentservice->name1);
4759 
4760 					my_free(temp_servicedependency->dependent_service_description);
4761 					temp_servicedependency->dependent_service_description = (char *)strdup(temp_dependentservice->name2);
4762 
4763 					/* Same host servicegroups dependencies: Use dependentservice host_name for master host_name */
4764 					if(same_host_servicedependency == TRUE)
4765 						temp_servicedependency->host_name = (char*)strdup(temp_dependentservice->name1);
4766 
4767 					/* clear the dependent servicegroup */
4768 					temp_servicedependency->have_dependent_servicegroup_name = FALSE;
4769 					my_free(temp_servicedependency->dependent_servicegroup_name);
4770 
4771 					if(temp_servicedependency->dependent_host_name == NULL || temp_servicedependency->dependent_service_description == NULL) {
4772 						xodtemplate_free_memberlist(&dependent_servicelist);
4773 						return ERROR;
4774 						}
4775 
4776 					first_item = FALSE;
4777 					continue;
4778 					}
4779 
4780 				/* duplicate service dependency definition */
4781 				/* Same host servicegroups dependencies: Use dependentservice host_name for master host_name instead of undefined (not yet) master host_name */
4782 				if(same_host_servicedependency == TRUE)
4783 					result = xodtemplate_duplicate_servicedependency(temp_servicedependency, temp_dependentservice->name1, temp_servicedependency->service_description, NULL, NULL, temp_dependentservice->name1, temp_dependentservice->name2, NULL, NULL);
4784 				else
4785 					result = xodtemplate_duplicate_servicedependency(temp_servicedependency, temp_servicedependency->host_name, temp_servicedependency->service_description, NULL, NULL, temp_dependentservice->name1, temp_dependentservice->name2, NULL, NULL);
4786 
4787 				/* exit on error */
4788 				if(result == ERROR) {
4789 					xodtemplate_free_memberlist(&dependent_servicelist);
4790 					return ERROR;
4791 					}
4792 				}
4793 
4794 			/* free memory we used for service list */
4795 			xodtemplate_free_memberlist(&dependent_servicelist);
4796 			}
4797 		}
4798 
4799 
4800 #ifdef DEBUG_SERVICE_DEPENDENCIES
4801 	printf("\n");
4802 	for(temp_servicedependency = xodtemplate_servicedependency_list; temp_servicedependency != NULL; temp_servicedependency = temp_servicedependency->next) {
4803 		printf("2**) H: %s  HG: %s  SG: %s  SD: %s  DH: %s  DHG: %s  DSG: %s  DSD: %s\n", temp_servicedependency->host_name, temp_servicedependency->hostgroup_name, temp_servicedependency->servicegroup_name, temp_servicedependency->service_description, temp_servicedependency->dependent_host_name, temp_servicedependency->dependent_hostgroup_name, temp_servicedependency->dependent_servicegroup_name, temp_servicedependency->dependent_service_description);
4804 		}
4805 #endif
4806 
4807 
4808 	/****** PROCESS SERVICE DEPENDENCY DEPENDENT HOSTS/HOSTGROUPS/SERVICES *****/
4809 	for(temp_servicedependency = xodtemplate_servicedependency_list; temp_servicedependency != NULL; temp_servicedependency = temp_servicedependency->next) {
4810 
4811 		/* skip templates */
4812 		if(temp_servicedependency->register_object == 0)
4813 			continue;
4814 
4815 		/* ADDED 02/04/2007 - special case for "same host" dependencies */
4816 		if(temp_servicedependency->dependent_host_name == NULL && temp_servicedependency->dependent_hostgroup_name == NULL) {
4817 			if(temp_servicedependency->host_name)
4818 				temp_servicedependency->dependent_host_name = (char *)strdup(temp_servicedependency->host_name);
4819 			}
4820 
4821 		/* expand dependent hosts/hostgroups into a list of host names */
4822 		if(temp_servicedependency->dependent_host_name != NULL || temp_servicedependency->dependent_hostgroup_name != NULL) {
4823 
4824 			dependent_hostlist = xodtemplate_expand_hostgroups_and_hosts(temp_servicedependency->dependent_hostgroup_name, temp_servicedependency->dependent_host_name, temp_servicedependency->_config_file, temp_servicedependency->_start_line);
4825 			if(dependent_hostlist == NULL && allow_empty_hostgroup_assignment == 0) {
4826 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand dependent hostgroups and/or hosts specified in service dependency (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_servicedependency->_config_file), temp_servicedependency->_start_line);
4827 				return ERROR;
4828 				}
4829 
4830 			/* save service descriptions for later */
4831 			if(temp_servicedependency->dependent_service_description)
4832 				service_descriptions = (char *)strdup(temp_servicedependency->dependent_service_description);
4833 
4834 			/* for each host, expand dependent services */
4835 			first_item = TRUE;
4836 			for(temp_dependenthost = dependent_hostlist; temp_dependenthost != NULL; temp_dependenthost = temp_dependenthost->next) {
4837 
4838 				dependent_servicelist = xodtemplate_expand_servicegroups_and_services(NULL, temp_dependenthost->name1, service_descriptions, temp_servicedependency->_config_file, temp_servicedependency->_start_line);
4839 				if(dependent_servicelist == NULL) {
4840 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand dependent services specified in service dependency (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_servicedependency->_config_file), temp_servicedependency->_start_line);
4841 					return ERROR;
4842 					}
4843 
4844 				/* duplicate service dependency entries */
4845 				for(temp_dependentservice = dependent_servicelist; temp_dependentservice != NULL; temp_dependentservice = temp_dependentservice->next) {
4846 
4847 					/* just in case */
4848 					if(temp_dependentservice->name1 == NULL || temp_dependentservice->name2 == NULL)
4849 						continue;
4850 
4851 					/* if this is the first duplication, use the existing entry */
4852 					if(first_item == TRUE) {
4853 
4854 						my_free(temp_servicedependency->dependent_host_name);
4855 						temp_servicedependency->dependent_host_name = (char *)strdup(temp_dependentservice->name1);
4856 
4857 						my_free(temp_servicedependency->dependent_service_description);
4858 						temp_servicedependency->dependent_service_description = (char *)strdup(temp_dependentservice->name2);
4859 
4860 						if(temp_servicedependency->dependent_host_name == NULL || temp_servicedependency->dependent_service_description == NULL) {
4861 							xodtemplate_free_memberlist(&dependent_servicelist);
4862 							xodtemplate_free_memberlist(&dependent_hostlist);
4863 							return ERROR;
4864 							}
4865 
4866 						first_item = FALSE;
4867 						continue;
4868 						}
4869 
4870 					/* duplicate service dependency definition */
4871 					result = xodtemplate_duplicate_servicedependency(temp_servicedependency, temp_servicedependency->host_name, temp_servicedependency->service_description, NULL, NULL, temp_dependentservice->name1, temp_dependentservice->name2, NULL, NULL);
4872 
4873 					/* exit on error */
4874 					if(result == ERROR) {
4875 						xodtemplate_free_memberlist(&dependent_servicelist);
4876 						xodtemplate_free_memberlist(&dependent_hostlist);
4877 						return ERROR;
4878 						}
4879 					}
4880 
4881 				/* free memory we used for service list */
4882 				xodtemplate_free_memberlist(&dependent_servicelist);
4883 				}
4884 
4885 			/* free service descriptions */
4886 			my_free(service_descriptions);
4887 
4888 			/* free memory we used for host list */
4889 			xodtemplate_free_memberlist(&dependent_hostlist);
4890 			}
4891 		}
4892 
4893 
4894 #ifdef DEBUG_SERVICE_DEPENDENCIES
4895 	printf("\n");
4896 	for(temp_servicedependency = xodtemplate_servicedependency_list; temp_servicedependency != NULL; temp_servicedependency = temp_servicedependency->next) {
4897 		printf("3**)  MAS: %s/%s  DEP: %s/%s\n", temp_servicedependency->host_name, temp_servicedependency->service_description, temp_servicedependency->dependent_host_name, temp_servicedependency->dependent_service_description);
4898 		}
4899 #endif
4900 
4901 
4902 	/****** DUPLICATE HOSTEXTINFO DEFINITIONS WITH ONE OR MORE HOSTGROUP AND/OR HOST NAMES ******/
4903 	for(temp_hostextinfo = xodtemplate_hostextinfo_list; temp_hostextinfo != NULL; temp_hostextinfo = temp_hostextinfo->next) {
4904 
4905 		/* skip definitions without enough data */
4906 		if(temp_hostextinfo->hostgroup_name == NULL && temp_hostextinfo->host_name == NULL)
4907 			continue;
4908 
4909 		/* get list of hosts */
4910 		master_hostlist = xodtemplate_expand_hostgroups_and_hosts(temp_hostextinfo->hostgroup_name, temp_hostextinfo->host_name, temp_hostextinfo->_config_file, temp_hostextinfo->_start_line);
4911 		if(master_hostlist == NULL) {
4912 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand hostgroups and/or hosts specified in extended host info (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_hostextinfo->_config_file), temp_hostextinfo->_start_line);
4913 			return ERROR;
4914 			}
4915 
4916 		/* add a copy of the definition for every host in the hostgroup/host name list */
4917 		first_item = TRUE;
4918 		for(temp_masterhost = master_hostlist; temp_masterhost != NULL; temp_masterhost = temp_masterhost->next) {
4919 
4920 			/* if this is the first duplication, use the existing entry */
4921 			if(first_item == TRUE) {
4922 
4923 				my_free(temp_hostextinfo->host_name);
4924 				temp_hostextinfo->host_name = (char *)strdup(temp_masterhost->name1);
4925 				if(temp_hostextinfo->host_name == NULL) {
4926 					xodtemplate_free_memberlist(&master_hostlist);
4927 					return ERROR;
4928 					}
4929 				first_item = FALSE;
4930 				continue;
4931 				}
4932 
4933 			/* duplicate hostextinfo definition */
4934 			result = xodtemplate_duplicate_hostextinfo(temp_hostextinfo, temp_masterhost->name1);
4935 
4936 			/* exit on error */
4937 			if(result == ERROR) {
4938 				xodtemplate_free_memberlist(&master_hostlist);
4939 				return ERROR;
4940 				}
4941 			}
4942 
4943 		/* free memory we used for host list */
4944 		xodtemplate_free_memberlist(&master_hostlist);
4945 		}
4946 
4947 
4948 	/****** DUPLICATE SERVICEEXTINFO DEFINITIONS WITH ONE OR MORE HOSTGROUP AND/OR HOST NAMES ******/
4949 	for(temp_serviceextinfo = xodtemplate_serviceextinfo_list; temp_serviceextinfo != NULL; temp_serviceextinfo = temp_serviceextinfo->next) {
4950 
4951 		/* skip definitions without enough data */
4952 		if(temp_serviceextinfo->hostgroup_name == NULL && temp_serviceextinfo->host_name == NULL)
4953 			continue;
4954 
4955 		/* get list of hosts */
4956 		master_hostlist = xodtemplate_expand_hostgroups_and_hosts(temp_serviceextinfo->hostgroup_name, temp_serviceextinfo->host_name, temp_serviceextinfo->_config_file, temp_serviceextinfo->_start_line);
4957 		if(master_hostlist == NULL) {
4958 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand hostgroups and/or hosts specified in extended service info (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_serviceextinfo->_config_file), temp_serviceextinfo->_start_line);
4959 			return ERROR;
4960 			}
4961 
4962 		/* add a copy of the definition for every host in the hostgroup/host name list */
4963 		first_item = TRUE;
4964 		for(temp_masterhost = master_hostlist; temp_masterhost != NULL; temp_masterhost = temp_masterhost->next) {
4965 
4966 			/* existing definition gets first host name */
4967 			if(first_item == TRUE) {
4968 				my_free(temp_serviceextinfo->host_name);
4969 				temp_serviceextinfo->host_name = (char *)strdup(temp_masterhost->name1);
4970 				if(temp_serviceextinfo->host_name == NULL) {
4971 					xodtemplate_free_memberlist(&master_hostlist);
4972 					return ERROR;
4973 					}
4974 				first_item = FALSE;
4975 				continue;
4976 				}
4977 
4978 			/* duplicate serviceextinfo definition */
4979 			result = xodtemplate_duplicate_serviceextinfo(temp_serviceextinfo, temp_masterhost->name1);
4980 
4981 			/* exit on error */
4982 			if(result == ERROR) {
4983 				xodtemplate_free_memberlist(&master_hostlist);
4984 				return ERROR;
4985 				}
4986 			}
4987 
4988 		/* free memory we used for host list */
4989 		xodtemplate_free_memberlist(&master_hostlist);
4990 		}
4991 
4992 
4993 	/***************************************/
4994 	/* SKIPLIST STUFF FOR FAST SORT/SEARCH */
4995 	/***************************************/
4996 
4997 	/* host escalations */
4998 	for(temp_hostescalation = xodtemplate_hostescalation_list; temp_hostescalation != NULL; temp_hostescalation = temp_hostescalation->next) {
4999 
5000 		/* skip escalations that shouldn't be registered */
5001 		if(temp_hostescalation->register_object == FALSE)
5002 			continue;
5003 
5004 		/* skip escalation definitions without enough data */
5005 		if(temp_hostescalation->host_name == NULL)
5006 			continue;
5007 
5008 		result = skiplist_insert(xobject_skiplists[X_HOSTESCALATION_SKIPLIST], (void *)temp_hostescalation);
5009 		switch(result) {
5010 			case SKIPLIST_OK:
5011 				result = OK;
5012 				break;
5013 			default:
5014 				result = ERROR;
5015 				break;
5016 			}
5017 		}
5018 
5019 	/* service escalations */
5020 	for(temp_serviceescalation = xodtemplate_serviceescalation_list; temp_serviceescalation != NULL; temp_serviceescalation = temp_serviceescalation->next) {
5021 
5022 		/* skip escalations that shouldn't be registered */
5023 		if(temp_serviceescalation->register_object == FALSE)
5024 			continue;
5025 
5026 		/* skip escalation definitions without enough data */
5027 		if(temp_serviceescalation->host_name == NULL || temp_serviceescalation->service_description == NULL)
5028 			continue;
5029 
5030 		result = skiplist_insert(xobject_skiplists[X_SERVICEESCALATION_SKIPLIST], (void *)temp_serviceescalation);
5031 		switch(result) {
5032 			case SKIPLIST_OK:
5033 				result = OK;
5034 				break;
5035 			default:
5036 				result = ERROR;
5037 				break;
5038 			}
5039 		}
5040 
5041 	/* host dependencies */
5042 	for(temp_hostdependency = xodtemplate_hostdependency_list; temp_hostdependency != NULL; temp_hostdependency = temp_hostdependency->next) {
5043 
5044 		/* skip dependencys that shouldn't be registered */
5045 		if(temp_hostdependency->register_object == FALSE)
5046 			continue;
5047 
5048 		/* skip dependency definitions without enough data */
5049 		if(temp_hostdependency->host_name == NULL)
5050 			continue;
5051 
5052 		result = skiplist_insert(xobject_skiplists[X_HOSTDEPENDENCY_SKIPLIST], (void *)temp_hostdependency);
5053 		switch(result) {
5054 			case SKIPLIST_OK:
5055 				result = OK;
5056 				break;
5057 			default:
5058 				result = ERROR;
5059 				break;
5060 			}
5061 		}
5062 
5063 	/* service dependencies */
5064 	for(temp_servicedependency = xodtemplate_servicedependency_list; temp_servicedependency != NULL; temp_servicedependency = temp_servicedependency->next) {
5065 
5066 		/* skip dependencys that shouldn't be registered */
5067 		if(temp_servicedependency->register_object == FALSE)
5068 			continue;
5069 
5070 		/* skip dependency definitions without enough data */
5071 		if(temp_servicedependency->dependent_host_name == NULL || temp_servicedependency->dependent_service_description == NULL)
5072 			continue;
5073 
5074 		result = skiplist_insert(xobject_skiplists[X_SERVICEDEPENDENCY_SKIPLIST], (void *)temp_servicedependency);
5075 		switch(result) {
5076 			case SKIPLIST_OK:
5077 				result = OK;
5078 				break;
5079 			default:
5080 				result = ERROR;
5081 				break;
5082 			}
5083 		}
5084 
5085 	/* host extinfo */
5086 	/* NOT NEEDED */
5087 
5088 	/* service extinfo */
5089 	/* NOT NEEDED */
5090 
5091 	return OK;
5092 	}
5093 
5094 
5095 
5096 /* duplicates a service definition (with a new host name) */
xodtemplate_duplicate_service(xodtemplate_service * temp_service,char * host_name)5097 int xodtemplate_duplicate_service(xodtemplate_service *temp_service, char *host_name) {
5098 	xodtemplate_service *new_service = NULL;
5099 	xodtemplate_customvariablesmember *temp_customvariablesmember = NULL;
5100 	int error = FALSE;
5101 
5102 	/* allocate zero'd out memory for a new service definition */
5103 	new_service = (xodtemplate_service *)calloc(1, sizeof(xodtemplate_service));
5104 	if(new_service == NULL)
5105 		return ERROR;
5106 
5107 	/* standard items */
5108 	new_service->has_been_resolved = temp_service->has_been_resolved;
5109 	new_service->register_object = temp_service->register_object;
5110 	new_service->_config_file = temp_service->_config_file;
5111 	new_service->_start_line = temp_service->_start_line;
5112 	/*tag service apply on host group*/
5113 	xodtemplate_set_service_is_from_hostgroup(new_service);
5114 
5115 	/* string defaults */
5116 	new_service->have_hostgroup_name = temp_service->have_hostgroup_name;
5117 	new_service->have_host_name = temp_service->have_host_name;
5118 	new_service->have_service_description = temp_service->have_service_description;
5119 	new_service->have_display_name = temp_service->have_display_name;
5120 	new_service->have_service_groups = temp_service->have_service_groups;
5121 	new_service->have_check_command = temp_service->have_check_command;
5122 	new_service->have_check_period = temp_service->have_check_period;
5123 	new_service->have_event_handler = temp_service->have_event_handler;
5124 	new_service->have_notification_period = temp_service->have_notification_period;
5125 	new_service->have_contact_groups = temp_service->have_contact_groups;
5126 	new_service->have_contacts = temp_service->have_contacts;
5127 	new_service->have_failure_prediction_options = temp_service->have_failure_prediction_options;
5128 	new_service->have_notes = temp_service->have_notes;
5129 	new_service->have_notes_url = temp_service->have_notes_url;
5130 	new_service->have_action_url = temp_service->have_action_url;
5131 	new_service->have_icon_image = temp_service->have_icon_image;
5132 	new_service->have_icon_image_alt = temp_service->have_icon_image_alt;
5133 
5134 	/* allocate memory for and copy string members of service definition (host name provided, DO NOT duplicate hostgroup member!)*/
5135 	if(temp_service->host_name != NULL && (new_service->host_name = (char *)strdup(host_name)) == NULL)
5136 		error = TRUE;
5137 	if(temp_service->template != NULL && (new_service->template = (char *)strdup(temp_service->template)) == NULL)
5138 		error = TRUE;
5139 	if(temp_service->name != NULL && (new_service->name = (char *)strdup(temp_service->name)) == NULL)
5140 		error = TRUE;
5141 	if(temp_service->service_description != NULL && (new_service->service_description = (char *)strdup(temp_service->service_description)) == NULL)
5142 		error = TRUE;
5143 	if(temp_service->display_name != NULL && (new_service->display_name = (char *)strdup(temp_service->display_name)) == NULL)
5144 		error = TRUE;
5145 	if(temp_service->service_groups != NULL && (new_service->service_groups = (char *)strdup(temp_service->service_groups)) == NULL)
5146 		error = TRUE;
5147 	if(temp_service->check_command != NULL && (new_service->check_command = (char *)strdup(temp_service->check_command)) == NULL)
5148 		error = TRUE;
5149 	if(temp_service->check_period != NULL && (new_service->check_period = (char *)strdup(temp_service->check_period)) == NULL)
5150 		error = TRUE;
5151 	if(temp_service->event_handler != NULL && (new_service->event_handler = (char *)strdup(temp_service->event_handler)) == NULL)
5152 		error = TRUE;
5153 	if(temp_service->notification_period != NULL && (new_service->notification_period = (char *)strdup(temp_service->notification_period)) == NULL)
5154 		error = TRUE;
5155 	if(temp_service->contact_groups != NULL && (new_service->contact_groups = (char *)strdup(temp_service->contact_groups)) == NULL)
5156 		error = TRUE;
5157 	if(temp_service->contacts != NULL && (new_service->contacts = (char *)strdup(temp_service->contacts)) == NULL)
5158 		error = TRUE;
5159 	if(temp_service->failure_prediction_options != NULL && (new_service->failure_prediction_options = (char *)strdup(temp_service->failure_prediction_options)) == NULL)
5160 		error = TRUE;
5161 	if(temp_service->notes != NULL && (new_service->notes = (char *)strdup(temp_service->notes)) == NULL)
5162 		error = TRUE;
5163 	if(temp_service->notes_url != NULL && (new_service->notes_url = (char *)strdup(temp_service->notes_url)) == NULL)
5164 		error = TRUE;
5165 	if(temp_service->action_url != NULL && (new_service->action_url = (char *)strdup(temp_service->action_url)) == NULL)
5166 		error = TRUE;
5167 	if(temp_service->icon_image != NULL && (new_service->icon_image = (char *)strdup(temp_service->icon_image)) == NULL)
5168 		error = TRUE;
5169 	if(temp_service->icon_image_alt != NULL && (new_service->icon_image_alt = (char *)strdup(temp_service->icon_image_alt)) == NULL)
5170 		error = TRUE;
5171 
5172 	if(error == TRUE) {
5173 		my_free(new_service->host_name);
5174 		my_free(new_service->template);
5175 		my_free(new_service->name);
5176 		my_free(new_service->service_description);
5177 		my_free(new_service->display_name);
5178 		my_free(new_service->service_groups);
5179 		my_free(new_service->check_command);
5180 		my_free(new_service->check_period);
5181 		my_free(new_service->event_handler);
5182 		my_free(new_service->notification_period);
5183 		my_free(new_service->contact_groups);
5184 		my_free(new_service->contacts);
5185 		my_free(new_service->failure_prediction_options);
5186 		my_free(new_service->notes);
5187 		my_free(new_service->notes_url);
5188 		my_free(new_service->action_url);
5189 		my_free(new_service->icon_image);
5190 		my_free(new_service->icon_image_alt);
5191 		my_free(new_service);
5192 		return ERROR;
5193 		}
5194 
5195 	/* duplicate custom variables */
5196 	for(temp_customvariablesmember = temp_service->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next)
5197 		xodtemplate_add_custom_variable_to_service(new_service, temp_customvariablesmember->variable_name, temp_customvariablesmember->variable_value);
5198 
5199 	/* duplicate non-string members */
5200 	new_service->initial_state = temp_service->initial_state;
5201 	new_service->max_check_attempts = temp_service->max_check_attempts;
5202 	new_service->have_max_check_attempts = temp_service->have_max_check_attempts;
5203 	new_service->check_interval = temp_service->check_interval;
5204 	new_service->have_check_interval = temp_service->have_check_interval;
5205 	new_service->retry_interval = temp_service->retry_interval;
5206 	new_service->have_retry_interval = temp_service->have_retry_interval;
5207 	new_service->active_checks_enabled = temp_service->active_checks_enabled;
5208 	new_service->have_active_checks_enabled = temp_service->have_active_checks_enabled;
5209 	new_service->passive_checks_enabled = temp_service->passive_checks_enabled;
5210 	new_service->have_passive_checks_enabled = temp_service->have_passive_checks_enabled;
5211 	new_service->parallelize_check = temp_service->parallelize_check;
5212 	new_service->have_parallelize_check = temp_service->have_parallelize_check;
5213 	new_service->is_volatile = temp_service->is_volatile;
5214 	new_service->have_is_volatile = temp_service->have_is_volatile;
5215 	new_service->obsess_over_service = temp_service->obsess_over_service;
5216 	new_service->have_obsess_over_service = temp_service->have_obsess_over_service;
5217 	new_service->event_handler_enabled = temp_service->event_handler_enabled;
5218 	new_service->have_event_handler_enabled = temp_service->have_event_handler_enabled;
5219 	new_service->check_freshness = temp_service->check_freshness;
5220 	new_service->have_check_freshness = temp_service->have_check_freshness;
5221 	new_service->freshness_threshold = temp_service->freshness_threshold;
5222 	new_service->have_freshness_threshold = temp_service->have_freshness_threshold;
5223 	new_service->flap_detection_enabled = temp_service->flap_detection_enabled;
5224 	new_service->have_flap_detection_enabled = temp_service->have_flap_detection_enabled;
5225 	new_service->low_flap_threshold = temp_service->low_flap_threshold;
5226 	new_service->have_low_flap_threshold = temp_service->have_low_flap_threshold;
5227 	new_service->high_flap_threshold = temp_service->high_flap_threshold;
5228 	new_service->have_high_flap_threshold = temp_service->have_high_flap_threshold;
5229 	new_service->flap_detection_on_ok = temp_service->flap_detection_on_ok;
5230 	new_service->flap_detection_on_warning = temp_service->flap_detection_on_warning;
5231 	new_service->flap_detection_on_unknown = temp_service->flap_detection_on_unknown;
5232 	new_service->flap_detection_on_critical = temp_service->flap_detection_on_critical;
5233 	new_service->have_flap_detection_options = temp_service->have_flap_detection_options;
5234 	new_service->notify_on_unknown = temp_service->notify_on_unknown;
5235 	new_service->notify_on_warning = temp_service->notify_on_warning;
5236 	new_service->notify_on_critical = temp_service->notify_on_critical;
5237 	new_service->notify_on_recovery = temp_service->notify_on_recovery;
5238 	new_service->notify_on_flapping = temp_service->notify_on_flapping;
5239 	new_service->notify_on_downtime = temp_service->notify_on_downtime;
5240 	new_service->have_notification_options = temp_service->have_notification_options;
5241 	new_service->notifications_enabled = temp_service->notifications_enabled;
5242 	new_service->have_notifications_enabled = temp_service->have_notifications_enabled;
5243 	new_service->notification_interval = temp_service->notification_interval;
5244 	new_service->have_notification_interval = temp_service->have_notification_interval;
5245 	new_service->first_notification_delay = temp_service->first_notification_delay;
5246 	new_service->have_first_notification_delay = temp_service->have_first_notification_delay;
5247 	new_service->stalk_on_ok = temp_service->stalk_on_ok;
5248 	new_service->stalk_on_unknown = temp_service->stalk_on_unknown;
5249 	new_service->stalk_on_warning = temp_service->stalk_on_warning;
5250 	new_service->stalk_on_critical = temp_service->stalk_on_critical;
5251 	new_service->have_stalking_options = temp_service->have_stalking_options;
5252 	new_service->process_perf_data = temp_service->process_perf_data;
5253 	new_service->have_process_perf_data = temp_service->have_process_perf_data;
5254 	new_service->failure_prediction_enabled = temp_service->failure_prediction_enabled;
5255 	new_service->have_failure_prediction_enabled = temp_service->have_failure_prediction_enabled;
5256 	new_service->retain_status_information = temp_service->retain_status_information;
5257 	new_service->have_retain_status_information = temp_service->have_retain_status_information;
5258 	new_service->retain_nonstatus_information = temp_service->retain_nonstatus_information;
5259 	new_service->have_retain_nonstatus_information = temp_service->have_retain_nonstatus_information;
5260 
5261 	/* add new service to head of list in memory */
5262 	new_service->next = xodtemplate_service_list;
5263 	xodtemplate_service_list = new_service;
5264 
5265 	return OK;
5266 	}
5267 
5268 
5269 
5270 
5271 /* duplicates a host escalation definition (with a new host name) */
xodtemplate_duplicate_hostescalation(xodtemplate_hostescalation * temp_hostescalation,char * host_name)5272 int xodtemplate_duplicate_hostescalation(xodtemplate_hostescalation *temp_hostescalation, char *host_name) {
5273 	xodtemplate_hostescalation *new_hostescalation = NULL;
5274 	int error = FALSE;
5275 
5276 
5277 	/* allocate zero'd out memory for a new host escalation definition */
5278 	new_hostescalation = (xodtemplate_hostescalation *)calloc(1, sizeof(xodtemplate_hostescalation));
5279 	if(new_hostescalation == NULL)
5280 		return ERROR;
5281 
5282 	/* standard items */
5283 	new_hostescalation->has_been_resolved = temp_hostescalation->has_been_resolved;
5284 	new_hostescalation->register_object = temp_hostescalation->register_object;
5285 	new_hostescalation->_config_file = temp_hostescalation->_config_file;
5286 	new_hostescalation->_start_line = temp_hostescalation->_start_line;
5287 
5288 	/* string defaults */
5289 	new_hostescalation->have_hostgroup_name = temp_hostescalation->have_hostgroup_name;
5290 	new_hostescalation->have_host_name = (host_name) ? TRUE : FALSE;
5291 	new_hostescalation->have_contact_groups = temp_hostescalation->have_contact_groups;
5292 	new_hostescalation->have_contacts = temp_hostescalation->have_contacts;
5293 	new_hostescalation->have_escalation_period = temp_hostescalation->have_escalation_period;
5294 
5295 	/* allocate memory for and copy string members of hostescalation definition */
5296 	if(host_name != NULL && (new_hostescalation->host_name = (char *)strdup(host_name)) == NULL)
5297 		error = TRUE;
5298 
5299 	if(temp_hostescalation->template != NULL && (new_hostescalation->template = (char *)strdup(temp_hostescalation->template)) == NULL)
5300 		error = TRUE;
5301 	if(temp_hostescalation->name != NULL && (new_hostescalation->name = (char *)strdup(temp_hostescalation->name)) == NULL)
5302 		error = TRUE;
5303 	if(temp_hostescalation->contact_groups != NULL && (new_hostescalation->contact_groups = (char *)strdup(temp_hostescalation->contact_groups)) == NULL)
5304 		error = TRUE;
5305 	if(temp_hostescalation->contacts != NULL && (new_hostescalation->contacts = (char *)strdup(temp_hostescalation->contacts)) == NULL)
5306 		error = TRUE;
5307 	if(temp_hostescalation->escalation_period != NULL && (new_hostescalation->escalation_period = (char *)strdup(temp_hostescalation->escalation_period)) == NULL)
5308 		error = TRUE;
5309 
5310 	if(error == TRUE) {
5311 		my_free(new_hostescalation->escalation_period);
5312 		my_free(new_hostescalation->contact_groups);
5313 		my_free(new_hostescalation->contacts);
5314 		my_free(new_hostescalation->host_name);
5315 		my_free(new_hostescalation->template);
5316 		my_free(new_hostescalation->name);
5317 		my_free(new_hostescalation);
5318 		return ERROR;
5319 		}
5320 
5321 	/* duplicate non-string members */
5322 	new_hostescalation->first_notification = temp_hostescalation->first_notification;
5323 	new_hostescalation->last_notification = temp_hostescalation->last_notification;
5324 	new_hostescalation->have_first_notification = temp_hostescalation->have_first_notification;
5325 	new_hostescalation->have_last_notification = temp_hostescalation->have_last_notification;
5326 	new_hostescalation->notification_interval = temp_hostescalation->notification_interval;
5327 	new_hostescalation->have_notification_interval = temp_hostescalation->have_notification_interval;
5328 	new_hostescalation->escalate_on_down = temp_hostescalation->escalate_on_down;
5329 	new_hostescalation->escalate_on_unreachable = temp_hostescalation->escalate_on_unreachable;
5330 	new_hostescalation->escalate_on_recovery = temp_hostescalation->escalate_on_recovery;
5331 	new_hostescalation->have_escalation_options = temp_hostescalation->have_escalation_options;
5332 
5333 	/* add new hostescalation to head of list in memory */
5334 	new_hostescalation->next = xodtemplate_hostescalation_list;
5335 	xodtemplate_hostescalation_list = new_hostescalation;
5336 
5337 	return OK;
5338 	}
5339 
5340 
5341 
5342 /* duplicates a service escalation definition (with a new host name and/or service description) */
xodtemplate_duplicate_serviceescalation(xodtemplate_serviceescalation * temp_serviceescalation,char * host_name,char * svc_description)5343 int xodtemplate_duplicate_serviceescalation(xodtemplate_serviceescalation *temp_serviceescalation, char *host_name, char *svc_description) {
5344 	xodtemplate_serviceescalation *new_serviceescalation = NULL;
5345 	int error = FALSE;
5346 
5347 	/* allocate zero'd out memory for a new service escalation definition */
5348 	new_serviceescalation = (xodtemplate_serviceescalation *)calloc(1, sizeof(xodtemplate_serviceescalation));
5349 	if(new_serviceescalation == NULL)
5350 		return ERROR;
5351 
5352 	/* standard items */
5353 	new_serviceescalation->has_been_resolved = temp_serviceescalation->has_been_resolved;
5354 	new_serviceescalation->register_object = temp_serviceescalation->register_object;
5355 	new_serviceescalation->_config_file = temp_serviceescalation->_config_file;
5356 	new_serviceescalation->_start_line = temp_serviceescalation->_start_line;
5357 
5358 	/* string defaults */
5359 	new_serviceescalation->have_servicegroup_name = FALSE;
5360 	new_serviceescalation->have_hostgroup_name = FALSE;
5361 	new_serviceescalation->have_host_name = (host_name) ? TRUE : FALSE;
5362 	new_serviceescalation->have_service_description = (svc_description) ? TRUE : FALSE;
5363 	new_serviceescalation->have_contact_groups = temp_serviceescalation->have_contact_groups;
5364 	new_serviceescalation->have_contacts = temp_serviceescalation->have_contacts;
5365 	new_serviceescalation->have_escalation_period = temp_serviceescalation->have_escalation_period;
5366 
5367 	/* allocate memory for and copy string members of serviceescalation definition */
5368 	if(host_name != NULL && (new_serviceescalation->host_name = (char *)strdup(host_name)) == NULL)
5369 		error = TRUE;
5370 	if(svc_description != NULL && (new_serviceescalation->service_description = (char *)strdup(svc_description)) == NULL)
5371 		error = TRUE;
5372 
5373 	if(temp_serviceescalation->template != NULL && (new_serviceescalation->template = (char *)strdup(temp_serviceescalation->template)) == NULL)
5374 		error = TRUE;
5375 	if(temp_serviceescalation->name != NULL && (new_serviceescalation->name = (char *)strdup(temp_serviceescalation->name)) == NULL)
5376 		error = TRUE;
5377 	if(temp_serviceescalation->contact_groups != NULL && (new_serviceescalation->contact_groups = (char *)strdup(temp_serviceescalation->contact_groups)) == NULL)
5378 		error = TRUE;
5379 	if(temp_serviceescalation->contacts != NULL && (new_serviceescalation->contacts = (char *)strdup(temp_serviceescalation->contacts)) == NULL)
5380 		error = TRUE;
5381 	if(temp_serviceescalation->escalation_period != NULL && (new_serviceescalation->escalation_period = (char *)strdup(temp_serviceescalation->escalation_period)) == NULL)
5382 		error = TRUE;
5383 
5384 	if(error == TRUE) {
5385 		my_free(new_serviceescalation->host_name);
5386 		my_free(new_serviceescalation->service_description);
5387 		my_free(new_serviceescalation->contact_groups);
5388 		my_free(new_serviceescalation->contacts);
5389 		my_free(new_serviceescalation->escalation_period);
5390 		my_free(new_serviceescalation->template);
5391 		my_free(new_serviceescalation->name);
5392 		my_free(new_serviceescalation);
5393 		return ERROR;
5394 		}
5395 
5396 	/* duplicate non-string members */
5397 	new_serviceescalation->first_notification = temp_serviceescalation->first_notification;
5398 	new_serviceescalation->last_notification = temp_serviceescalation->last_notification;
5399 	new_serviceescalation->have_first_notification = temp_serviceescalation->have_first_notification;
5400 	new_serviceescalation->have_last_notification = temp_serviceescalation->have_last_notification;
5401 	new_serviceescalation->notification_interval = temp_serviceescalation->notification_interval;
5402 	new_serviceescalation->have_notification_interval = temp_serviceescalation->have_notification_interval;
5403 	new_serviceescalation->escalate_on_warning = temp_serviceescalation->escalate_on_warning;
5404 	new_serviceescalation->escalate_on_unknown = temp_serviceescalation->escalate_on_unknown;
5405 	new_serviceescalation->escalate_on_critical = temp_serviceescalation->escalate_on_critical;
5406 	new_serviceescalation->escalate_on_recovery = temp_serviceescalation->escalate_on_recovery;
5407 	new_serviceescalation->have_escalation_options = temp_serviceescalation->have_escalation_options;
5408 
5409 	/* add new serviceescalation to head of list in memory */
5410 	new_serviceescalation->next = xodtemplate_serviceescalation_list;
5411 	xodtemplate_serviceescalation_list = new_serviceescalation;
5412 
5413 	return OK;
5414 	}
5415 
5416 
5417 
5418 /* duplicates a host dependency definition (with master and dependent host names) */
xodtemplate_duplicate_hostdependency(xodtemplate_hostdependency * temp_hostdependency,char * master_host_name,char * dependent_host_name)5419 int xodtemplate_duplicate_hostdependency(xodtemplate_hostdependency *temp_hostdependency, char *master_host_name, char *dependent_host_name) {
5420 	xodtemplate_hostdependency *new_hostdependency = NULL;
5421 	int error = FALSE;
5422 
5423 	/* allocate memory for a new host dependency definition */
5424 	new_hostdependency = (xodtemplate_hostdependency *)calloc(1, sizeof(xodtemplate_hostdependency));
5425 	if(new_hostdependency == NULL)
5426 		return ERROR;
5427 
5428 	/* standard items */
5429 	new_hostdependency->has_been_resolved = temp_hostdependency->has_been_resolved;
5430 	new_hostdependency->register_object = temp_hostdependency->register_object;
5431 	new_hostdependency->_config_file = temp_hostdependency->_config_file;
5432 	new_hostdependency->_start_line = temp_hostdependency->_start_line;
5433 
5434 	/* string defaults */
5435 	new_hostdependency->have_hostgroup_name = FALSE;
5436 	new_hostdependency->have_dependent_hostgroup_name = FALSE;
5437 	new_hostdependency->have_host_name = temp_hostdependency->have_host_name;
5438 	new_hostdependency->have_dependent_host_name = temp_hostdependency->have_dependent_host_name;
5439 	new_hostdependency->have_dependency_period = temp_hostdependency->have_dependency_period;
5440 
5441 	/* allocate memory for and copy string members of hostdependency definition */
5442 	if(master_host_name != NULL && (new_hostdependency->host_name = (char *)strdup(master_host_name)) == NULL)
5443 		error = TRUE;
5444 	if(dependent_host_name != NULL && (new_hostdependency->dependent_host_name = (char *)strdup(dependent_host_name)) == NULL)
5445 		error = TRUE;
5446 
5447 	if(temp_hostdependency->dependency_period != NULL && (new_hostdependency->dependency_period = (char *)strdup(temp_hostdependency->dependency_period)) == NULL)
5448 		error = TRUE;
5449 	if(temp_hostdependency->template != NULL && (new_hostdependency->template = (char *)strdup(temp_hostdependency->template)) == NULL)
5450 		error = TRUE;
5451 	if(temp_hostdependency->name != NULL && (new_hostdependency->name = (char *)strdup(temp_hostdependency->name)) == NULL)
5452 		error = TRUE;
5453 
5454 	if(error == TRUE) {
5455 		my_free(new_hostdependency->dependent_host_name);
5456 		my_free(new_hostdependency->host_name);
5457 		my_free(new_hostdependency->template);
5458 		my_free(new_hostdependency->name);
5459 		my_free(new_hostdependency);
5460 		return ERROR;
5461 		}
5462 
5463 	/* duplicate non-string members */
5464 	new_hostdependency->fail_notify_on_up = temp_hostdependency->fail_notify_on_up;
5465 	new_hostdependency->fail_notify_on_down = temp_hostdependency->fail_notify_on_down;
5466 	new_hostdependency->fail_notify_on_unreachable = temp_hostdependency->fail_notify_on_unreachable;
5467 	new_hostdependency->fail_notify_on_pending = temp_hostdependency->fail_notify_on_pending;
5468 	new_hostdependency->have_notification_dependency_options = temp_hostdependency->have_notification_dependency_options;
5469 	new_hostdependency->fail_execute_on_up = temp_hostdependency->fail_execute_on_up;
5470 	new_hostdependency->fail_execute_on_down = temp_hostdependency->fail_execute_on_down;
5471 	new_hostdependency->fail_execute_on_unreachable = temp_hostdependency->fail_execute_on_unreachable;
5472 	new_hostdependency->fail_execute_on_pending = temp_hostdependency->fail_execute_on_pending;
5473 	new_hostdependency->have_execution_dependency_options = temp_hostdependency->have_execution_dependency_options;
5474 	new_hostdependency->inherits_parent = temp_hostdependency->inherits_parent;
5475 	new_hostdependency->have_inherits_parent = temp_hostdependency->have_inherits_parent;
5476 
5477 	/* add new hostdependency to head of list in memory */
5478 	new_hostdependency->next = xodtemplate_hostdependency_list;
5479 	xodtemplate_hostdependency_list = new_hostdependency;
5480 
5481 	return OK;
5482 	}
5483 
5484 
5485 
5486 /* duplicates a service dependency definition */
xodtemplate_duplicate_servicedependency(xodtemplate_servicedependency * temp_servicedependency,char * master_host_name,char * master_service_description,char * master_hostgroup_name,char * master_servicegroup_name,char * dependent_host_name,char * dependent_service_description,char * dependent_hostgroup_name,char * dependent_servicegroup_name)5487 int xodtemplate_duplicate_servicedependency(xodtemplate_servicedependency *temp_servicedependency, char *master_host_name, char *master_service_description, char *master_hostgroup_name, char *master_servicegroup_name, char *dependent_host_name, char *dependent_service_description, char *dependent_hostgroup_name, char *dependent_servicegroup_name) {
5488 	xodtemplate_servicedependency *new_servicedependency = NULL;
5489 	int error = FALSE;
5490 
5491 	/* allocate memory for a new service dependency definition */
5492 	new_servicedependency = (xodtemplate_servicedependency *)calloc(1, sizeof(xodtemplate_servicedependency));
5493 	if(new_servicedependency == NULL)
5494 		return ERROR;
5495 
5496 	/* standard items */
5497 	new_servicedependency->has_been_resolved = temp_servicedependency->has_been_resolved;
5498 	new_servicedependency->register_object = temp_servicedependency->register_object;
5499 	new_servicedependency->_config_file = temp_servicedependency->_config_file;
5500 	new_servicedependency->_start_line = temp_servicedependency->_start_line;
5501 
5502 	/* string defaults */
5503 	new_servicedependency->have_host_name = (master_host_name) ? TRUE : FALSE;
5504 	new_servicedependency->have_service_description = (master_service_description) ? TRUE : FALSE;
5505 	new_servicedependency->have_hostgroup_name = (master_hostgroup_name) ? TRUE : FALSE;
5506 	new_servicedependency->have_servicegroup_name = (master_servicegroup_name) ? TRUE : FALSE;
5507 
5508 	new_servicedependency->have_dependent_host_name = (dependent_host_name) ? TRUE : FALSE;
5509 	new_servicedependency->have_dependent_service_description = (dependent_service_description) ? TRUE : FALSE;
5510 	new_servicedependency->have_dependent_hostgroup_name = (dependent_hostgroup_name) ? TRUE : FALSE;
5511 	new_servicedependency->have_dependent_servicegroup_name = (dependent_servicegroup_name) ? TRUE : FALSE;
5512 
5513 	new_servicedependency->have_dependency_period = temp_servicedependency->have_dependency_period;
5514 
5515 	/* duplicate strings */
5516 	if(master_host_name != NULL && (new_servicedependency->host_name = (char *)strdup(master_host_name)) == NULL)
5517 		error = TRUE;
5518 	if(master_service_description != NULL && (new_servicedependency->service_description = (char *)strdup(master_service_description)) == NULL)
5519 		error = TRUE;
5520 	if(master_hostgroup_name != NULL && (new_servicedependency->hostgroup_name = (char *)strdup(master_hostgroup_name)) == NULL)
5521 		error = TRUE;
5522 	if(master_servicegroup_name != NULL && (new_servicedependency->servicegroup_name = (char *)strdup(master_servicegroup_name)) == NULL)
5523 		error = TRUE;
5524 	if(dependent_host_name != NULL && (new_servicedependency->dependent_host_name = (char *)strdup(dependent_host_name)) == NULL)
5525 		error = TRUE;
5526 	if(dependent_service_description != NULL && (new_servicedependency->dependent_service_description = (char *)strdup(dependent_service_description)) == NULL)
5527 		error = TRUE;
5528 	if(dependent_hostgroup_name != NULL && (new_servicedependency->dependent_hostgroup_name = (char *)strdup(dependent_hostgroup_name)) == NULL)
5529 		error = TRUE;
5530 	if(dependent_servicegroup_name != NULL && (new_servicedependency->dependent_servicegroup_name = (char *)strdup(dependent_servicegroup_name)) == NULL)
5531 		error = TRUE;
5532 
5533 	if(temp_servicedependency->dependency_period != NULL && (new_servicedependency->dependency_period = (char *)strdup(temp_servicedependency->dependency_period)) == NULL)
5534 		error = TRUE;
5535 	if(temp_servicedependency->template != NULL && (new_servicedependency->template = (char *)strdup(temp_servicedependency->template)) == NULL)
5536 		error = TRUE;
5537 	if(temp_servicedependency->name != NULL && (new_servicedependency->name = (char *)strdup(temp_servicedependency->name)) == NULL)
5538 		error = TRUE;
5539 
5540 	if(error == TRUE) {
5541 		my_free(new_servicedependency->host_name);
5542 		my_free(new_servicedependency->service_description);
5543 		my_free(new_servicedependency->hostgroup_name);
5544 		my_free(new_servicedependency->servicegroup_name);
5545 		my_free(new_servicedependency->dependent_host_name);
5546 		my_free(new_servicedependency->dependent_service_description);
5547 		my_free(new_servicedependency->dependent_hostgroup_name);
5548 		my_free(new_servicedependency->dependent_servicegroup_name);
5549 		my_free(new_servicedependency->dependency_period);
5550 		my_free(new_servicedependency->template);
5551 		my_free(new_servicedependency->name);
5552 		my_free(new_servicedependency);
5553 		return ERROR;
5554 		}
5555 
5556 	/* duplicate non-string members */
5557 	new_servicedependency->fail_notify_on_ok = temp_servicedependency->fail_notify_on_ok;
5558 	new_servicedependency->fail_notify_on_unknown = temp_servicedependency->fail_notify_on_unknown;
5559 	new_servicedependency->fail_notify_on_warning = temp_servicedependency->fail_notify_on_warning;
5560 	new_servicedependency->fail_notify_on_critical = temp_servicedependency->fail_notify_on_critical;
5561 	new_servicedependency->fail_notify_on_pending = temp_servicedependency->fail_notify_on_pending;
5562 	new_servicedependency->have_notification_dependency_options = temp_servicedependency->have_notification_dependency_options;
5563 	new_servicedependency->fail_execute_on_ok = temp_servicedependency->fail_execute_on_ok;
5564 	new_servicedependency->fail_execute_on_unknown = temp_servicedependency->fail_execute_on_unknown;
5565 	new_servicedependency->fail_execute_on_warning = temp_servicedependency->fail_execute_on_warning;
5566 	new_servicedependency->fail_execute_on_critical = temp_servicedependency->fail_execute_on_critical;
5567 	new_servicedependency->fail_execute_on_pending = temp_servicedependency->fail_execute_on_pending;
5568 	new_servicedependency->have_execution_dependency_options = temp_servicedependency->have_execution_dependency_options;
5569 	new_servicedependency->inherits_parent = temp_servicedependency->inherits_parent;
5570 	new_servicedependency->have_inherits_parent = temp_servicedependency->have_inherits_parent;
5571 
5572 	/* add new servicedependency to head of list in memory */
5573 	new_servicedependency->next = xodtemplate_servicedependency_list;
5574 	xodtemplate_servicedependency_list = new_servicedependency;
5575 
5576 	return OK;
5577 	}
5578 
5579 
5580 
5581 /* duplicates a hostextinfo object definition */
xodtemplate_duplicate_hostextinfo(xodtemplate_hostextinfo * this_hostextinfo,char * host_name)5582 int xodtemplate_duplicate_hostextinfo(xodtemplate_hostextinfo *this_hostextinfo, char *host_name) {
5583 	xodtemplate_hostextinfo *new_hostextinfo = NULL;
5584 	int error = FALSE;
5585 
5586 	/* allocate zero'd out memory for a new hostextinfo object */
5587 	new_hostextinfo = (xodtemplate_hostextinfo *)calloc(1, sizeof(xodtemplate_hostextinfo));
5588 	if(new_hostextinfo == NULL)
5589 		return ERROR;
5590 
5591 	/* standard items */
5592 	new_hostextinfo->has_been_resolved = this_hostextinfo->has_been_resolved;
5593 	new_hostextinfo->register_object = this_hostextinfo->register_object;
5594 	new_hostextinfo->_config_file = this_hostextinfo->_config_file;
5595 	new_hostextinfo->_start_line = this_hostextinfo->_start_line;
5596 
5597 	/* string defaults */
5598 	new_hostextinfo->have_host_name = this_hostextinfo->have_host_name;
5599 	new_hostextinfo->have_hostgroup_name = this_hostextinfo->have_hostgroup_name;
5600 	new_hostextinfo->have_notes = this_hostextinfo->have_notes;
5601 	new_hostextinfo->have_notes_url = this_hostextinfo->have_notes_url;
5602 	new_hostextinfo->have_action_url = this_hostextinfo->have_action_url;
5603 	new_hostextinfo->have_icon_image = this_hostextinfo->have_icon_image;
5604 	new_hostextinfo->have_icon_image_alt = this_hostextinfo->have_icon_image_alt;
5605 	new_hostextinfo->have_vrml_image = this_hostextinfo->have_vrml_image;
5606 	new_hostextinfo->have_statusmap_image = this_hostextinfo->have_statusmap_image;
5607 
5608 	/* duplicate strings (host_name member is passed in) */
5609 	if(host_name != NULL && (new_hostextinfo->host_name = (char *)strdup(host_name)) == NULL)
5610 		error = TRUE;
5611 	if(this_hostextinfo->template != NULL && (new_hostextinfo->template = (char *)strdup(this_hostextinfo->template)) == NULL)
5612 		error = TRUE;
5613 	if(this_hostextinfo->name != NULL && (new_hostextinfo->name = (char *)strdup(this_hostextinfo->name)) == NULL)
5614 		error = TRUE;
5615 	if(this_hostextinfo->notes != NULL && (new_hostextinfo->notes = (char *)strdup(this_hostextinfo->notes)) == NULL)
5616 		error = TRUE;
5617 	if(this_hostextinfo->notes_url != NULL && (new_hostextinfo->notes_url = (char *)strdup(this_hostextinfo->notes_url)) == NULL)
5618 		error = TRUE;
5619 	if(this_hostextinfo->action_url != NULL && (new_hostextinfo->action_url = (char *)strdup(this_hostextinfo->action_url)) == NULL)
5620 		error = TRUE;
5621 	if(this_hostextinfo->icon_image != NULL && (new_hostextinfo->icon_image = (char *)strdup(this_hostextinfo->icon_image)) == NULL)
5622 		error = TRUE;
5623 	if(this_hostextinfo->icon_image_alt != NULL && (new_hostextinfo->icon_image_alt = (char *)strdup(this_hostextinfo->icon_image_alt)) == NULL)
5624 		error = TRUE;
5625 	if(this_hostextinfo->vrml_image != NULL && (new_hostextinfo->vrml_image = (char *)strdup(this_hostextinfo->vrml_image)) == NULL)
5626 		error = TRUE;
5627 	if(this_hostextinfo->statusmap_image != NULL && (new_hostextinfo->statusmap_image = (char *)strdup(this_hostextinfo->statusmap_image)) == NULL)
5628 		error = TRUE;
5629 
5630 	if(error == TRUE) {
5631 		my_free(new_hostextinfo->host_name);
5632 		my_free(new_hostextinfo->template);
5633 		my_free(new_hostextinfo->name);
5634 		my_free(new_hostextinfo->notes);
5635 		my_free(new_hostextinfo->notes_url);
5636 		my_free(new_hostextinfo->action_url);
5637 		my_free(new_hostextinfo->icon_image);
5638 		my_free(new_hostextinfo->icon_image_alt);
5639 		my_free(new_hostextinfo->vrml_image);
5640 		my_free(new_hostextinfo->statusmap_image);
5641 		my_free(new_hostextinfo);
5642 		return ERROR;
5643 		}
5644 
5645 	/* duplicate non-string members */
5646 	new_hostextinfo->x_2d = this_hostextinfo->x_2d;
5647 	new_hostextinfo->y_2d = this_hostextinfo->y_2d;
5648 	new_hostextinfo->have_2d_coords = this_hostextinfo->have_2d_coords;
5649 	new_hostextinfo->x_3d = this_hostextinfo->x_3d;
5650 	new_hostextinfo->y_3d = this_hostextinfo->y_3d;
5651 	new_hostextinfo->z_3d = this_hostextinfo->z_3d;
5652 	new_hostextinfo->have_3d_coords = this_hostextinfo->have_3d_coords;
5653 
5654 	/* add new object to head of list */
5655 	new_hostextinfo->next = xodtemplate_hostextinfo_list;
5656 	xodtemplate_hostextinfo_list = new_hostextinfo;
5657 
5658 	return OK;
5659 	}
5660 
5661 
5662 
5663 /* duplicates a serviceextinfo object definition */
xodtemplate_duplicate_serviceextinfo(xodtemplate_serviceextinfo * this_serviceextinfo,char * host_name)5664 int xodtemplate_duplicate_serviceextinfo(xodtemplate_serviceextinfo *this_serviceextinfo, char *host_name) {
5665 	xodtemplate_serviceextinfo *new_serviceextinfo = NULL;
5666 	int error = FALSE;
5667 
5668 	/* allocate zero'd out object for a new serviceextinfo object */
5669 	new_serviceextinfo = (xodtemplate_serviceextinfo *)calloc(1, sizeof(xodtemplate_serviceextinfo));
5670 	if(new_serviceextinfo == NULL)
5671 		return ERROR;
5672 
5673 	/* standard items */
5674 	new_serviceextinfo->has_been_resolved = this_serviceextinfo->has_been_resolved;
5675 	new_serviceextinfo->register_object = this_serviceextinfo->register_object;
5676 	new_serviceextinfo->_config_file = this_serviceextinfo->_config_file;
5677 	new_serviceextinfo->_start_line = this_serviceextinfo->_start_line;
5678 
5679 	/* string defaults */
5680 	new_serviceextinfo->have_host_name = this_serviceextinfo->have_host_name;
5681 	new_serviceextinfo->have_service_description = this_serviceextinfo->have_service_description;
5682 	new_serviceextinfo->have_hostgroup_name = this_serviceextinfo->have_hostgroup_name;
5683 	new_serviceextinfo->have_notes = this_serviceextinfo->have_notes;
5684 	new_serviceextinfo->have_notes_url = this_serviceextinfo->have_notes_url;
5685 	new_serviceextinfo->have_action_url = this_serviceextinfo->have_action_url;
5686 	new_serviceextinfo->have_icon_image = this_serviceextinfo->have_icon_image;
5687 	new_serviceextinfo->have_icon_image_alt = this_serviceextinfo->have_icon_image_alt;
5688 
5689 	/* duplicate strings (host_name member is passed in) */
5690 	if(host_name != NULL && (new_serviceextinfo->host_name = (char *)strdup(host_name)) == NULL)
5691 		error = TRUE;
5692 	if(this_serviceextinfo->template != NULL && (new_serviceextinfo->template = (char *)strdup(this_serviceextinfo->template)) == NULL)
5693 		error = TRUE;
5694 	if(this_serviceextinfo->name != NULL && (new_serviceextinfo->name = (char *)strdup(this_serviceextinfo->name)) == NULL)
5695 		error = TRUE;
5696 	if(this_serviceextinfo->service_description != NULL && (new_serviceextinfo->service_description = (char *)strdup(this_serviceextinfo->service_description)) == NULL)
5697 		error = TRUE;
5698 	if(this_serviceextinfo->notes != NULL && (new_serviceextinfo->notes = (char *)strdup(this_serviceextinfo->notes)) == NULL)
5699 		error = TRUE;
5700 	if(this_serviceextinfo->notes_url != NULL && (new_serviceextinfo->notes_url = (char *)strdup(this_serviceextinfo->notes_url)) == NULL)
5701 		error = TRUE;
5702 	if(this_serviceextinfo->action_url != NULL && (new_serviceextinfo->action_url = (char *)strdup(this_serviceextinfo->action_url)) == NULL)
5703 		error = TRUE;
5704 	if(this_serviceextinfo->icon_image != NULL && (new_serviceextinfo->icon_image = (char *)strdup(this_serviceextinfo->icon_image)) == NULL)
5705 		error = TRUE;
5706 	if(this_serviceextinfo->icon_image_alt != NULL && (new_serviceextinfo->icon_image_alt = (char *)strdup(this_serviceextinfo->icon_image_alt)) == NULL)
5707 		error = TRUE;
5708 
5709 	if(error == TRUE) {
5710 		my_free(new_serviceextinfo->host_name);
5711 		my_free(new_serviceextinfo->template);
5712 		my_free(new_serviceextinfo->name);
5713 		my_free(new_serviceextinfo->service_description);
5714 		my_free(new_serviceextinfo->notes);
5715 		my_free(new_serviceextinfo->notes_url);
5716 		my_free(new_serviceextinfo->action_url);
5717 		my_free(new_serviceextinfo->icon_image);
5718 		my_free(new_serviceextinfo->icon_image_alt);
5719 		my_free(new_serviceextinfo);
5720 		return ERROR;
5721 		}
5722 
5723 	/* add new object to head of list */
5724 	new_serviceextinfo->next = xodtemplate_serviceextinfo_list;
5725 	xodtemplate_serviceextinfo_list = new_serviceextinfo;
5726 
5727 	return OK;
5728 	}
5729 
5730 #endif
5731 
5732 
5733 /******************************************************************/
5734 /***************** OBJECT RESOLUTION FUNCTIONS ********************/
5735 /******************************************************************/
5736 
5737 #ifdef NSCORE
5738 
5739 /* inherit object properties */
5740 /* some missing defaults (notification options, etc.) are also applied here */
xodtemplate_inherit_object_properties(void)5741 int xodtemplate_inherit_object_properties(void) {
5742 	xodtemplate_host *temp_host = NULL;
5743 	xodtemplate_service *temp_service = NULL;
5744 	xodtemplate_serviceescalation *temp_serviceescalation = NULL;
5745 	xodtemplate_hostescalation *temp_hostescalation = NULL;
5746 
5747 
5748 	/* fill in missing defaults for hosts... */
5749 	for(temp_host = xodtemplate_host_list; temp_host != NULL; temp_host = temp_host->next) {
5750 
5751 		/* if notification options are missing, assume all */
5752 		if(temp_host->have_notification_options == FALSE) {
5753 			temp_host->notify_on_down = TRUE;
5754 			temp_host->notify_on_unreachable = TRUE;
5755 			temp_host->notify_on_recovery = TRUE;
5756 			temp_host->notify_on_flapping = TRUE;
5757 			temp_host->notify_on_downtime = TRUE;
5758 			temp_host->have_notification_options = TRUE;
5759 			}
5760 		}
5761 
5762 	/* services inherit some properties from their associated host... */
5763 	for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) {
5764 
5765 		/* find the host */
5766 		if((temp_host = xodtemplate_find_real_host(temp_service->host_name)) == NULL)
5767 			continue;
5768 
5769 		/* services inherit contact groups from host if not already specified */
5770 		if(temp_service->have_contact_groups == FALSE && temp_host->have_contact_groups == TRUE && temp_host->contact_groups != NULL) {
5771 			temp_service->contact_groups = (char *)strdup(temp_host->contact_groups);
5772 			temp_service->have_contact_groups = TRUE;
5773 			}
5774 
5775 		/* services inherit contacts from host if not already specified */
5776 		if(temp_service->have_contacts == FALSE && temp_host->have_contacts == TRUE && temp_host->contacts != NULL) {
5777 			temp_service->contacts = (char *)strdup(temp_host->contacts);
5778 			temp_service->have_contacts = TRUE;
5779 			}
5780 
5781 		/* services inherit notification interval from host if not already specified */
5782 		if(temp_service->have_notification_interval == FALSE && temp_host->have_notification_interval == TRUE) {
5783 			temp_service->notification_interval = temp_host->notification_interval;
5784 			temp_service->have_notification_interval = TRUE;
5785 			}
5786 
5787 		/* services inherit notification period from host if not already specified */
5788 		if(temp_service->have_notification_period == FALSE && temp_host->have_notification_period == TRUE && temp_host->notification_period != NULL) {
5789 			temp_service->notification_period = (char *)strdup(temp_host->notification_period);
5790 			temp_service->have_notification_period = TRUE;
5791 			}
5792 
5793 		/* if notification options are missing, assume all */
5794 		if(temp_service->have_notification_options == FALSE) {
5795 			temp_service->notify_on_unknown = TRUE;
5796 			temp_service->notify_on_warning = TRUE;
5797 			temp_service->notify_on_critical = TRUE;
5798 			temp_service->notify_on_recovery = TRUE;
5799 			temp_service->notify_on_flapping = TRUE;
5800 			temp_service->notify_on_downtime = TRUE;
5801 			temp_service->have_notification_options = TRUE;
5802 			}
5803 		}
5804 
5805 	/* service escalations inherit some properties from their associated service... */
5806 	for(temp_serviceescalation = xodtemplate_serviceescalation_list; temp_serviceescalation != NULL; temp_serviceescalation = temp_serviceescalation->next) {
5807 
5808 		/* find the service */
5809 		if((temp_service = xodtemplate_find_real_service(temp_serviceescalation->host_name, temp_serviceescalation->service_description)) == NULL)
5810 			continue;
5811 
5812 		/* service escalations inherit contact groups from service if not already specified */
5813 		if(temp_serviceescalation->have_contact_groups == FALSE && temp_service->have_contact_groups == TRUE && temp_service->contact_groups != NULL) {
5814 			temp_serviceescalation->contact_groups = (char *)strdup(temp_service->contact_groups);
5815 			temp_serviceescalation->have_contact_groups = TRUE;
5816 			}
5817 
5818 		/* SPECIAL RULE 10/04/07 - additive inheritance from service's contactgroup(s) */
5819 		if(temp_serviceescalation->contact_groups != NULL && temp_serviceescalation->contact_groups[0] == '+')
5820 			xodtemplate_get_inherited_string(&temp_service->have_contact_groups, &temp_service->contact_groups, &temp_serviceescalation->have_contact_groups, &temp_serviceescalation->contact_groups);
5821 
5822 		/* service escalations inherit contacts from service if not already specified */
5823 		if(temp_serviceescalation->have_contacts == FALSE && temp_service->have_contacts == TRUE && temp_service->contacts != NULL) {
5824 			temp_serviceescalation->contacts = (char *)strdup(temp_service->contacts);
5825 			temp_serviceescalation->have_contacts = TRUE;
5826 			}
5827 
5828 		/* SPECIAL RULE 10/04/07 - additive inheritance from service's contact(s) */
5829 		if(temp_serviceescalation->contacts != NULL && temp_serviceescalation->contacts[0] == '+')
5830 			xodtemplate_get_inherited_string(&temp_service->have_contacts, &temp_service->contacts, &temp_serviceescalation->have_contacts, &temp_serviceescalation->contacts);
5831 
5832 		/* service escalations inherit notification interval from service if not already defined */
5833 		if(temp_serviceescalation->have_notification_interval == FALSE && temp_service->have_notification_interval == TRUE) {
5834 			temp_serviceescalation->notification_interval = temp_service->notification_interval;
5835 			temp_serviceescalation->have_notification_interval = TRUE;
5836 			}
5837 
5838 		/* service escalations inherit escalation period from service if not already defined */
5839 		if(temp_serviceescalation->have_escalation_period == FALSE && temp_service->have_notification_period == TRUE && temp_service->notification_period != NULL) {
5840 			temp_serviceescalation->escalation_period = (char *)strdup(temp_service->notification_period);
5841 			temp_serviceescalation->have_escalation_period = TRUE;
5842 			}
5843 
5844 		/* if escalation options are missing, assume all */
5845 		if(temp_serviceescalation->have_escalation_options == FALSE) {
5846 			temp_serviceescalation->escalate_on_unknown = TRUE;
5847 			temp_serviceescalation->escalate_on_warning = TRUE;
5848 			temp_serviceescalation->escalate_on_critical = TRUE;
5849 			temp_serviceescalation->escalate_on_recovery = TRUE;
5850 			temp_serviceescalation->have_escalation_options = TRUE;
5851 			}
5852 
5853 		/* 03/05/08 clear additive string chars - not done in xodtemplate_clean_additive_strings() anymore */
5854 		xodtemplate_clean_additive_string(&temp_serviceescalation->contact_groups);
5855 		xodtemplate_clean_additive_string(&temp_serviceescalation->contacts);
5856 		}
5857 
5858 	/* host escalations inherit some properties from their associated host... */
5859 	for(temp_hostescalation = xodtemplate_hostescalation_list; temp_hostescalation != NULL; temp_hostescalation = temp_hostescalation->next) {
5860 
5861 		/* find the host */
5862 		if((temp_host = xodtemplate_find_real_host(temp_hostescalation->host_name)) == NULL)
5863 			continue;
5864 
5865 		/* host escalations inherit contact groups from service if not already specified */
5866 		if(temp_hostescalation->have_contact_groups == FALSE && temp_host->have_contact_groups == TRUE && temp_host->contact_groups != NULL) {
5867 			temp_hostescalation->contact_groups = (char *)strdup(temp_host->contact_groups);
5868 			temp_hostescalation->have_contact_groups = TRUE;
5869 			}
5870 
5871 		/* SPECIAL RULE 10/04/07 - additive inheritance from host's contactgroup(s) */
5872 		if(temp_hostescalation->contact_groups != NULL && temp_hostescalation->contact_groups[0] == '+')
5873 			xodtemplate_get_inherited_string(&temp_host->have_contact_groups, &temp_host->contact_groups, &temp_hostescalation->have_contact_groups, &temp_hostescalation->contact_groups);
5874 
5875 		/* host escalations inherit contacts from service if not already specified */
5876 		if(temp_hostescalation->have_contacts == FALSE && temp_host->have_contacts == TRUE && temp_host->contacts != NULL) {
5877 			temp_hostescalation->contacts = (char *)strdup(temp_host->contacts);
5878 			temp_hostescalation->have_contacts = TRUE;
5879 			}
5880 
5881 		/* SPECIAL RULE 10/04/07 - additive inheritance from host's contact(s) */
5882 		if(temp_hostescalation->contacts != NULL && temp_hostescalation->contacts[0] == '+')
5883 			xodtemplate_get_inherited_string(&temp_host->have_contacts, &temp_host->contacts, &temp_hostescalation->have_contacts, &temp_hostescalation->contacts);
5884 
5885 		/* host escalations inherit notification interval from host if not already defined */
5886 		if(temp_hostescalation->have_notification_interval == FALSE && temp_host->have_notification_interval == TRUE) {
5887 			temp_hostescalation->notification_interval = temp_host->notification_interval;
5888 			temp_hostescalation->have_notification_interval = TRUE;
5889 			}
5890 
5891 		/* host escalations inherit escalation period from host if not already defined */
5892 		if(temp_hostescalation->have_escalation_period == FALSE && temp_host->have_notification_period == TRUE && temp_host->notification_period != NULL) {
5893 			temp_hostescalation->escalation_period = (char *)strdup(temp_host->notification_period);
5894 			temp_hostescalation->have_escalation_period = TRUE;
5895 			}
5896 
5897 		/* if escalation options are missing, assume all */
5898 		if(temp_hostescalation->have_escalation_options == FALSE) {
5899 			temp_hostescalation->escalate_on_down = TRUE;
5900 			temp_hostescalation->escalate_on_unreachable = TRUE;
5901 			temp_hostescalation->escalate_on_recovery = TRUE;
5902 			temp_hostescalation->have_escalation_options = TRUE;
5903 			}
5904 
5905 		/* 03/05/08 clear additive string chars - not done in xodtemplate_clean_additive_strings() anymore */
5906 		xodtemplate_clean_additive_string(&temp_hostescalation->contact_groups);
5907 		xodtemplate_clean_additive_string(&temp_hostescalation->contacts);
5908 		}
5909 
5910 	return OK;
5911 	}
5912 
5913 #endif
5914 
5915 
5916 /******************************************************************/
5917 /***************** OBJECT RESOLUTION FUNCTIONS ********************/
5918 /******************************************************************/
5919 
5920 #ifdef NSCORE
5921 
5922 /* resolves object definitions */
xodtemplate_resolve_objects(void)5923 int xodtemplate_resolve_objects(void) {
5924 	xodtemplate_timeperiod *temp_timeperiod = NULL;
5925 	xodtemplate_command *temp_command = NULL;
5926 	xodtemplate_contactgroup *temp_contactgroup = NULL;
5927 	xodtemplate_hostgroup *temp_hostgroup = NULL;
5928 	xodtemplate_servicegroup *temp_servicegroup = NULL;
5929 	xodtemplate_servicedependency *temp_servicedependency = NULL;
5930 	xodtemplate_serviceescalation *temp_serviceescalation = NULL;
5931 	xodtemplate_contact *temp_contact = NULL;
5932 	xodtemplate_host *temp_host = NULL;
5933 	xodtemplate_service *temp_service = NULL;
5934 	xodtemplate_hostdependency *temp_hostdependency = NULL;
5935 	xodtemplate_hostescalation *temp_hostescalation = NULL;
5936 	xodtemplate_hostextinfo *temp_hostextinfo = NULL;
5937 	xodtemplate_serviceextinfo *temp_serviceextinfo = NULL;
5938 
5939 	/* resolve all timeperiod objects */
5940 	for(temp_timeperiod = xodtemplate_timeperiod_list; temp_timeperiod != NULL; temp_timeperiod = temp_timeperiod->next) {
5941 		if(xodtemplate_resolve_timeperiod(temp_timeperiod) == ERROR)
5942 			return ERROR;
5943 		}
5944 
5945 	/* resolve all command objects */
5946 	for(temp_command = xodtemplate_command_list; temp_command != NULL; temp_command = temp_command->next) {
5947 		if(xodtemplate_resolve_command(temp_command) == ERROR)
5948 			return ERROR;
5949 		}
5950 
5951 	/* resolve all contactgroup objects */
5952 	for(temp_contactgroup = xodtemplate_contactgroup_list; temp_contactgroup != NULL; temp_contactgroup = temp_contactgroup->next) {
5953 		if(xodtemplate_resolve_contactgroup(temp_contactgroup) == ERROR)
5954 			return ERROR;
5955 		}
5956 
5957 	/* resolve all hostgroup objects */
5958 	for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) {
5959 		if(xodtemplate_resolve_hostgroup(temp_hostgroup) == ERROR)
5960 			return ERROR;
5961 		}
5962 
5963 	/* resolve all servicegroup objects */
5964 	for(temp_servicegroup = xodtemplate_servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) {
5965 		if(xodtemplate_resolve_servicegroup(temp_servicegroup) == ERROR)
5966 			return ERROR;
5967 		}
5968 
5969 	/* resolve all servicedependency objects */
5970 	for(temp_servicedependency = xodtemplate_servicedependency_list; temp_servicedependency != NULL; temp_servicedependency = temp_servicedependency->next) {
5971 		if(xodtemplate_resolve_servicedependency(temp_servicedependency) == ERROR)
5972 			return ERROR;
5973 		}
5974 
5975 	/* resolve all serviceescalation objects */
5976 	for(temp_serviceescalation = xodtemplate_serviceescalation_list; temp_serviceescalation != NULL; temp_serviceescalation = temp_serviceescalation->next) {
5977 		if(xodtemplate_resolve_serviceescalation(temp_serviceescalation) == ERROR)
5978 			return ERROR;
5979 		}
5980 
5981 	/* resolve all contact objects */
5982 	for(temp_contact = xodtemplate_contact_list; temp_contact != NULL; temp_contact = temp_contact->next) {
5983 		if(xodtemplate_resolve_contact(temp_contact) == ERROR)
5984 			return ERROR;
5985 		}
5986 
5987 	/* resolve all host objects */
5988 	for(temp_host = xodtemplate_host_list; temp_host != NULL; temp_host = temp_host->next) {
5989 		if(xodtemplate_resolve_host(temp_host) == ERROR)
5990 			return ERROR;
5991 		}
5992 
5993 	/* resolve all service objects */
5994 	for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) {
5995 		if(xodtemplate_resolve_service(temp_service) == ERROR)
5996 			return ERROR;
5997 		}
5998 
5999 	/* resolve all hostdependency objects */
6000 	for(temp_hostdependency = xodtemplate_hostdependency_list; temp_hostdependency != NULL; temp_hostdependency = temp_hostdependency->next) {
6001 		if(xodtemplate_resolve_hostdependency(temp_hostdependency) == ERROR)
6002 			return ERROR;
6003 		}
6004 
6005 	/* resolve all hostescalation objects */
6006 	for(temp_hostescalation = xodtemplate_hostescalation_list; temp_hostescalation != NULL; temp_hostescalation = temp_hostescalation->next) {
6007 		if(xodtemplate_resolve_hostescalation(temp_hostescalation) == ERROR)
6008 			return ERROR;
6009 		}
6010 
6011 	/* resolve all hostextinfo objects */
6012 	for(temp_hostextinfo = xodtemplate_hostextinfo_list; temp_hostextinfo != NULL; temp_hostextinfo = temp_hostextinfo->next) {
6013 		if(xodtemplate_resolve_hostextinfo(temp_hostextinfo) == ERROR)
6014 			return ERROR;
6015 		}
6016 
6017 	/* resolve all serviceextinfo objects */
6018 	for(temp_serviceextinfo = xodtemplate_serviceextinfo_list; temp_serviceextinfo != NULL; temp_serviceextinfo = temp_serviceextinfo->next) {
6019 		if(xodtemplate_resolve_serviceextinfo(temp_serviceextinfo) == ERROR)
6020 			return ERROR;
6021 		}
6022 
6023 	return OK;
6024 	}
6025 
6026 
6027 
6028 /* resolves a timeperiod object */
xodtemplate_resolve_timeperiod(xodtemplate_timeperiod * this_timeperiod)6029 int xodtemplate_resolve_timeperiod(xodtemplate_timeperiod *this_timeperiod) {
6030 	char *temp_ptr = NULL;
6031 	char *template_names = NULL;
6032 	char *template_name_ptr = NULL;
6033 	xodtemplate_daterange *template_daterange = NULL;
6034 	xodtemplate_daterange *this_daterange = NULL;
6035 	xodtemplate_daterange *new_daterange = NULL;
6036 	xodtemplate_timeperiod *template_timeperiod = NULL;
6037 	int x;
6038 
6039 	/* return if this timeperiod has already been resolved */
6040 	if(this_timeperiod->has_been_resolved == TRUE)
6041 		return OK;
6042 
6043 	/* set the resolved flag */
6044 	this_timeperiod->has_been_resolved = TRUE;
6045 
6046 	/* return if we have no template */
6047 	if(this_timeperiod->template == NULL)
6048 		return OK;
6049 
6050 	if((template_names = (char *)strdup(this_timeperiod->template)) == NULL)
6051 		return ERROR;
6052 
6053 	/* apply all templates */
6054 	template_name_ptr = template_names;
6055 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
6056 
6057 		template_timeperiod = xodtemplate_find_timeperiod(temp_ptr);
6058 		if(template_timeperiod == NULL) {
6059 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in timeperiod definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_timeperiod->_config_file), this_timeperiod->_start_line);
6060 			my_free(template_names);
6061 			return ERROR;
6062 			}
6063 
6064 		/* resolve the template timeperiod... */
6065 		xodtemplate_resolve_timeperiod(template_timeperiod);
6066 
6067 		/* apply missing properties from template timeperiod... */
6068 		if(this_timeperiod->timeperiod_name == NULL && template_timeperiod->timeperiod_name != NULL)
6069 			this_timeperiod->timeperiod_name = (char *)strdup(template_timeperiod->timeperiod_name);
6070 		if(this_timeperiod->alias == NULL && template_timeperiod->alias != NULL)
6071 			this_timeperiod->alias = (char *)strdup(template_timeperiod->alias);
6072 		if(this_timeperiod->exclusions == NULL && template_timeperiod->exclusions != NULL)
6073 			this_timeperiod->exclusions = (char *)strdup(template_timeperiod->exclusions);
6074 		for(x = 0; x < 7; x++) {
6075 			if(this_timeperiod->timeranges[x] == NULL && template_timeperiod->timeranges[x] != NULL) {
6076 				this_timeperiod->timeranges[x] = (char *)strdup(template_timeperiod->timeranges[x]);
6077 				}
6078 			}
6079 		/* daterange exceptions require more work to apply missing ranges... */
6080 		for(x = 0; x < DATERANGE_TYPES; x++) {
6081 			for(template_daterange = template_timeperiod->exceptions[x]; template_daterange != NULL; template_daterange = template_daterange->next) {
6082 
6083 				/* see if this same daterange already exists in the timeperiod */
6084 				for(this_daterange = this_timeperiod->exceptions[x]; this_daterange != NULL; this_daterange = this_daterange->next) {
6085 					if((this_daterange->type == template_daterange->type) && (this_daterange->syear == template_daterange->syear) && (this_daterange->smon == template_daterange->smon) && (this_daterange->smday == template_daterange->smday) && (this_daterange->swday == template_daterange->swday) && (this_daterange->swday_offset == template_daterange->swday_offset) && (this_daterange->eyear == template_daterange->eyear) && (this_daterange->emon == template_daterange->emon) && (this_daterange->emday == template_daterange->emday) && (this_daterange->ewday == template_daterange->ewday) && (this_daterange->ewday_offset == template_daterange->ewday_offset) && (this_daterange->skip_interval == template_daterange->skip_interval))
6086 						break;
6087 					}
6088 
6089 				/* this daterange already exists in the timeperiod, so don't inherit it */
6090 				if(this_daterange != NULL)
6091 					continue;
6092 
6093 				/* inherit the daterange from the template */
6094 				if((new_daterange = (xodtemplate_daterange *)malloc(sizeof(xodtemplate_daterange))) == NULL)
6095 					continue;
6096 				new_daterange->type = template_daterange->type;
6097 				new_daterange->syear = template_daterange->syear;
6098 				new_daterange->smon = template_daterange->smon;
6099 				new_daterange->smday = template_daterange->smday;
6100 				new_daterange->swday = template_daterange->swday;
6101 				new_daterange->swday_offset = template_daterange->swday_offset;
6102 				new_daterange->eyear = template_daterange->eyear;
6103 				new_daterange->emon = template_daterange->emon;
6104 				new_daterange->emday = template_daterange->emday;
6105 				new_daterange->ewday = template_daterange->ewday;
6106 				new_daterange->ewday_offset = template_daterange->ewday_offset;
6107 				new_daterange->skip_interval = template_daterange->skip_interval;
6108 				new_daterange->timeranges = NULL;
6109 				if(template_daterange->timeranges != NULL)
6110 					new_daterange->timeranges = (char *)strdup(template_daterange->timeranges);
6111 
6112 				/* add new daterange to head of list (should it be added to the end instead?) */
6113 				new_daterange->next = this_timeperiod->exceptions[x];
6114 				this_timeperiod->exceptions[x] = new_daterange;
6115 				}
6116 			}
6117 		}
6118 
6119 	my_free(template_names);
6120 
6121 	return OK;
6122 	}
6123 
6124 
6125 
6126 
6127 /* resolves a command object */
xodtemplate_resolve_command(xodtemplate_command * this_command)6128 int xodtemplate_resolve_command(xodtemplate_command *this_command) {
6129 	char *temp_ptr = NULL;
6130 	char *template_names = NULL;
6131 	char *template_name_ptr = NULL;
6132 	xodtemplate_command *template_command = NULL;
6133 
6134 	/* return if this command has already been resolved */
6135 	if(this_command->has_been_resolved == TRUE)
6136 		return OK;
6137 
6138 	/* set the resolved flag */
6139 	this_command->has_been_resolved = TRUE;
6140 
6141 	/* return if we have no template */
6142 	if(this_command->template == NULL)
6143 		return OK;
6144 
6145 	if((template_names = (char *)strdup(this_command->template)) == NULL)
6146 		return ERROR;
6147 
6148 	/* apply all templates */
6149 	template_name_ptr = template_names;
6150 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
6151 
6152 		template_command = xodtemplate_find_command(temp_ptr);
6153 		if(template_command == NULL) {
6154 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in command definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_command->_config_file), this_command->_start_line);
6155 			my_free(template_names);
6156 			return ERROR;
6157 			}
6158 
6159 		/* resolve the template command... */
6160 		xodtemplate_resolve_command(template_command);
6161 
6162 		/* apply missing properties from template command... */
6163 		if(this_command->command_name == NULL && template_command->command_name != NULL)
6164 			this_command->command_name = (char *)strdup(template_command->command_name);
6165 		if(this_command->command_line == NULL && template_command->command_line != NULL)
6166 			this_command->command_line = (char *)strdup(template_command->command_line);
6167 		}
6168 
6169 	my_free(template_names);
6170 
6171 	return OK;
6172 	}
6173 
6174 
6175 
6176 
6177 /* resolves a contactgroup object */
xodtemplate_resolve_contactgroup(xodtemplate_contactgroup * this_contactgroup)6178 int xodtemplate_resolve_contactgroup(xodtemplate_contactgroup *this_contactgroup) {
6179 	char *temp_ptr = NULL;
6180 	char *template_names = NULL;
6181 	char *template_name_ptr = NULL;
6182 	xodtemplate_contactgroup *template_contactgroup = NULL;
6183 
6184 	/* return if this contactgroup has already been resolved */
6185 	if(this_contactgroup->has_been_resolved == TRUE)
6186 		return OK;
6187 
6188 	/* set the resolved flag */
6189 	this_contactgroup->has_been_resolved = TRUE;
6190 
6191 	/* return if we have no template */
6192 	if(this_contactgroup->template == NULL)
6193 		return OK;
6194 
6195 	if((template_names = (char *)strdup(this_contactgroup->template)) == NULL)
6196 		return ERROR;
6197 
6198 	/* apply all templates */
6199 	template_name_ptr = template_names;
6200 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
6201 
6202 		template_contactgroup = xodtemplate_find_contactgroup(temp_ptr);
6203 		if(template_contactgroup == NULL) {
6204 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in contactgroup definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_contactgroup->_config_file), this_contactgroup->_start_line);
6205 			my_free(template_names);
6206 			return ERROR;
6207 			}
6208 
6209 		/* resolve the template contactgroup... */
6210 		xodtemplate_resolve_contactgroup(template_contactgroup);
6211 
6212 		/* apply missing properties from template contactgroup... */
6213 		if(this_contactgroup->contactgroup_name == NULL && template_contactgroup->contactgroup_name != NULL)
6214 			this_contactgroup->contactgroup_name = (char *)strdup(template_contactgroup->contactgroup_name);
6215 		if(this_contactgroup->alias == NULL && template_contactgroup->alias != NULL)
6216 			this_contactgroup->alias = (char *)strdup(template_contactgroup->alias);
6217 
6218 		xodtemplate_get_inherited_string(&template_contactgroup->have_members, &template_contactgroup->members, &this_contactgroup->have_members, &this_contactgroup->members);
6219 		xodtemplate_get_inherited_string(&template_contactgroup->have_contactgroup_members, &template_contactgroup->contactgroup_members, &this_contactgroup->have_contactgroup_members, &this_contactgroup->contactgroup_members);
6220 
6221 		}
6222 
6223 	my_free(template_names);
6224 
6225 	return OK;
6226 	}
6227 
6228 
6229 
6230 
6231 /* resolves a hostgroup object */
xodtemplate_resolve_hostgroup(xodtemplate_hostgroup * this_hostgroup)6232 int xodtemplate_resolve_hostgroup(xodtemplate_hostgroup *this_hostgroup) {
6233 	char *temp_ptr = NULL;
6234 	char *template_names = NULL;
6235 	char *template_name_ptr = NULL;
6236 	xodtemplate_hostgroup *template_hostgroup = NULL;
6237 
6238 	/* return if this hostgroup has already been resolved */
6239 	if(this_hostgroup->has_been_resolved == TRUE)
6240 		return OK;
6241 
6242 	/* set the resolved flag */
6243 	this_hostgroup->has_been_resolved = TRUE;
6244 
6245 	/* return if we have no template */
6246 	if(this_hostgroup->template == NULL)
6247 		return OK;
6248 
6249 	if((template_names = (char *)strdup(this_hostgroup->template)) == NULL)
6250 		return ERROR;
6251 
6252 	/* apply all templates */
6253 	template_name_ptr = template_names;
6254 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
6255 
6256 		template_hostgroup = xodtemplate_find_hostgroup(temp_ptr);
6257 		if(template_hostgroup == NULL) {
6258 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in hostgroup definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_hostgroup->_config_file), this_hostgroup->_start_line);
6259 			my_free(template_names);
6260 			return ERROR;
6261 			}
6262 
6263 		/* resolve the template hostgroup... */
6264 		xodtemplate_resolve_hostgroup(template_hostgroup);
6265 
6266 		/* apply missing properties from template hostgroup... */
6267 		if(this_hostgroup->hostgroup_name == NULL && template_hostgroup->hostgroup_name != NULL)
6268 			this_hostgroup->hostgroup_name = (char *)strdup(template_hostgroup->hostgroup_name);
6269 		if(this_hostgroup->alias == NULL && template_hostgroup->alias != NULL)
6270 			this_hostgroup->alias = (char *)strdup(template_hostgroup->alias);
6271 
6272 		xodtemplate_get_inherited_string(&template_hostgroup->have_members, &template_hostgroup->members, &this_hostgroup->have_members, &this_hostgroup->members);
6273 		xodtemplate_get_inherited_string(&template_hostgroup->have_hostgroup_members, &template_hostgroup->hostgroup_members, &this_hostgroup->have_hostgroup_members, &this_hostgroup->hostgroup_members);
6274 
6275 		if(this_hostgroup->have_notes == FALSE && template_hostgroup->have_notes == TRUE) {
6276 			if(this_hostgroup->notes == NULL && template_hostgroup->notes != NULL)
6277 				this_hostgroup->notes = (char *)strdup(template_hostgroup->notes);
6278 			this_hostgroup->have_notes = TRUE;
6279 			}
6280 		if(this_hostgroup->have_notes_url == FALSE && template_hostgroup->have_notes_url == TRUE) {
6281 			if(this_hostgroup->notes_url == NULL && template_hostgroup->notes_url != NULL)
6282 				this_hostgroup->notes_url = (char *)strdup(template_hostgroup->notes_url);
6283 			this_hostgroup->have_notes_url = TRUE;
6284 			}
6285 		if(this_hostgroup->have_action_url == FALSE && template_hostgroup->have_action_url == TRUE) {
6286 			if(this_hostgroup->action_url == NULL && template_hostgroup->action_url != NULL)
6287 				this_hostgroup->action_url = (char *)strdup(template_hostgroup->action_url);
6288 			this_hostgroup->have_action_url = TRUE;
6289 			}
6290 		}
6291 
6292 	my_free(template_names);
6293 
6294 	return OK;
6295 	}
6296 
6297 
6298 
6299 
6300 /* resolves a servicegroup object */
xodtemplate_resolve_servicegroup(xodtemplate_servicegroup * this_servicegroup)6301 int xodtemplate_resolve_servicegroup(xodtemplate_servicegroup *this_servicegroup) {
6302 	char *temp_ptr = NULL;
6303 	char *template_names = NULL;
6304 	char *template_name_ptr = NULL;
6305 	xodtemplate_servicegroup *template_servicegroup = NULL;
6306 
6307 	/* return if this servicegroup has already been resolved */
6308 	if(this_servicegroup->has_been_resolved == TRUE)
6309 		return OK;
6310 
6311 	/* set the resolved flag */
6312 	this_servicegroup->has_been_resolved = TRUE;
6313 
6314 	/* return if we have no template */
6315 	if(this_servicegroup->template == NULL)
6316 		return OK;
6317 
6318 	if((template_names = (char *)strdup(this_servicegroup->template)) == NULL)
6319 		return ERROR;
6320 
6321 	/* apply all templates */
6322 	template_name_ptr = template_names;
6323 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
6324 
6325 		template_servicegroup = xodtemplate_find_servicegroup(temp_ptr);
6326 		if(template_servicegroup == NULL) {
6327 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in servicegroup definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_servicegroup->_config_file), this_servicegroup->_start_line);
6328 			my_free(template_names);
6329 			return ERROR;
6330 			}
6331 
6332 		/* resolve the template servicegroup... */
6333 		xodtemplate_resolve_servicegroup(template_servicegroup);
6334 
6335 		/* apply missing properties from template servicegroup... */
6336 		if(this_servicegroup->servicegroup_name == NULL && template_servicegroup->servicegroup_name != NULL)
6337 			this_servicegroup->servicegroup_name = (char *)strdup(template_servicegroup->servicegroup_name);
6338 		if(this_servicegroup->alias == NULL && template_servicegroup->alias != NULL)
6339 			this_servicegroup->alias = (char *)strdup(template_servicegroup->alias);
6340 
6341 		xodtemplate_get_inherited_string(&template_servicegroup->have_members, &template_servicegroup->members, &this_servicegroup->have_members, &this_servicegroup->members);
6342 		xodtemplate_get_inherited_string(&template_servicegroup->have_servicegroup_members, &template_servicegroup->servicegroup_members, &this_servicegroup->have_servicegroup_members, &this_servicegroup->servicegroup_members);
6343 
6344 		if(this_servicegroup->have_notes == FALSE && template_servicegroup->have_notes == TRUE) {
6345 			if(this_servicegroup->notes == NULL && template_servicegroup->notes != NULL)
6346 				this_servicegroup->notes = (char *)strdup(template_servicegroup->notes);
6347 			this_servicegroup->have_notes = TRUE;
6348 			}
6349 		if(this_servicegroup->have_notes_url == FALSE && template_servicegroup->have_notes_url == TRUE) {
6350 			if(this_servicegroup->notes_url == NULL && template_servicegroup->notes_url != NULL)
6351 				this_servicegroup->notes_url = (char *)strdup(template_servicegroup->notes_url);
6352 			this_servicegroup->have_notes_url = TRUE;
6353 			}
6354 		if(this_servicegroup->have_action_url == FALSE && template_servicegroup->have_action_url == TRUE) {
6355 			if(this_servicegroup->action_url == NULL && template_servicegroup->action_url != NULL)
6356 				this_servicegroup->action_url = (char *)strdup(template_servicegroup->action_url);
6357 			this_servicegroup->have_action_url = TRUE;
6358 			}
6359 		}
6360 
6361 	my_free(template_names);
6362 
6363 	return OK;
6364 	}
6365 
6366 
6367 /* resolves a servicedependency object */
xodtemplate_resolve_servicedependency(xodtemplate_servicedependency * this_servicedependency)6368 int xodtemplate_resolve_servicedependency(xodtemplate_servicedependency *this_servicedependency) {
6369 	char *temp_ptr = NULL;
6370 	char *template_names = NULL;
6371 	char *template_name_ptr = NULL;
6372 	xodtemplate_servicedependency *template_servicedependency = NULL;
6373 
6374 	/* return if this servicedependency has already been resolved */
6375 	if(this_servicedependency->has_been_resolved == TRUE)
6376 		return OK;
6377 
6378 	/* set the resolved flag */
6379 	this_servicedependency->has_been_resolved = TRUE;
6380 
6381 	/* return if we have no template */
6382 	if(this_servicedependency->template == NULL)
6383 		return OK;
6384 
6385 	if((template_names = (char *)strdup(this_servicedependency->template)) == NULL)
6386 		return ERROR;
6387 
6388 	/* apply all templates */
6389 	template_name_ptr = template_names;
6390 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
6391 
6392 		template_servicedependency = xodtemplate_find_servicedependency(temp_ptr);
6393 		if(template_servicedependency == NULL) {
6394 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in service dependency definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_servicedependency->_config_file), this_servicedependency->_start_line);
6395 			my_free(template_names);
6396 			return ERROR;
6397 			}
6398 
6399 		/* resolve the template servicedependency... */
6400 		xodtemplate_resolve_servicedependency(template_servicedependency);
6401 
6402 		/* apply missing properties from template servicedependency... */
6403 		xodtemplate_get_inherited_string(&template_servicedependency->have_servicegroup_name, &template_servicedependency->servicegroup_name, &this_servicedependency->have_servicegroup_name, &this_servicedependency->servicegroup_name);
6404 		xodtemplate_get_inherited_string(&template_servicedependency->have_hostgroup_name, &template_servicedependency->hostgroup_name, &this_servicedependency->have_hostgroup_name, &this_servicedependency->hostgroup_name);
6405 		xodtemplate_get_inherited_string(&template_servicedependency->have_host_name, &template_servicedependency->host_name, &this_servicedependency->have_host_name, &this_servicedependency->host_name);
6406 		xodtemplate_get_inherited_string(&template_servicedependency->have_service_description, &template_servicedependency->service_description, &this_servicedependency->have_service_description, &this_servicedependency->service_description);
6407 		xodtemplate_get_inherited_string(&template_servicedependency->have_dependent_servicegroup_name, &template_servicedependency->dependent_servicegroup_name, &this_servicedependency->have_dependent_servicegroup_name, &this_servicedependency->dependent_servicegroup_name);
6408 		xodtemplate_get_inherited_string(&template_servicedependency->have_dependent_hostgroup_name, &template_servicedependency->dependent_hostgroup_name, &this_servicedependency->have_dependent_hostgroup_name, &this_servicedependency->dependent_hostgroup_name);
6409 		xodtemplate_get_inherited_string(&template_servicedependency->have_dependent_host_name, &template_servicedependency->dependent_host_name, &this_servicedependency->have_dependent_host_name, &this_servicedependency->dependent_host_name);
6410 		xodtemplate_get_inherited_string(&template_servicedependency->have_dependent_service_description, &template_servicedependency->dependent_service_description, &this_servicedependency->have_dependent_service_description, &this_servicedependency->dependent_service_description);
6411 
6412 		if(this_servicedependency->have_dependency_period == FALSE && template_servicedependency->have_dependency_period == TRUE) {
6413 			if(this_servicedependency->dependency_period == NULL && template_servicedependency->dependency_period != NULL)
6414 				this_servicedependency->dependency_period = (char *)strdup(template_servicedependency->dependency_period);
6415 			this_servicedependency->have_dependency_period = TRUE;
6416 			}
6417 		if(this_servicedependency->have_inherits_parent == FALSE && template_servicedependency->have_inherits_parent == TRUE) {
6418 			this_servicedependency->inherits_parent = template_servicedependency->inherits_parent;
6419 			this_servicedependency->have_inherits_parent = TRUE;
6420 			}
6421 		if(this_servicedependency->have_execution_dependency_options == FALSE && template_servicedependency->have_execution_dependency_options == TRUE) {
6422 			this_servicedependency->fail_execute_on_ok = template_servicedependency->fail_execute_on_ok;
6423 			this_servicedependency->fail_execute_on_unknown = template_servicedependency->fail_execute_on_unknown;
6424 			this_servicedependency->fail_execute_on_warning = template_servicedependency->fail_execute_on_warning;
6425 			this_servicedependency->fail_execute_on_critical = template_servicedependency->fail_execute_on_critical;
6426 			this_servicedependency->fail_execute_on_pending = template_servicedependency->fail_execute_on_pending;
6427 			this_servicedependency->have_execution_dependency_options = TRUE;
6428 			}
6429 		if(this_servicedependency->have_notification_dependency_options == FALSE && template_servicedependency->have_notification_dependency_options == TRUE) {
6430 			this_servicedependency->fail_notify_on_ok = template_servicedependency->fail_notify_on_ok;
6431 			this_servicedependency->fail_notify_on_unknown = template_servicedependency->fail_notify_on_unknown;
6432 			this_servicedependency->fail_notify_on_warning = template_servicedependency->fail_notify_on_warning;
6433 			this_servicedependency->fail_notify_on_critical = template_servicedependency->fail_notify_on_critical;
6434 			this_servicedependency->fail_notify_on_pending = template_servicedependency->fail_notify_on_pending;
6435 			this_servicedependency->have_notification_dependency_options = TRUE;
6436 			}
6437 		}
6438 
6439 	my_free(template_names);
6440 
6441 	return OK;
6442 	}
6443 
6444 
6445 /* resolves a serviceescalation object */
xodtemplate_resolve_serviceescalation(xodtemplate_serviceescalation * this_serviceescalation)6446 int xodtemplate_resolve_serviceescalation(xodtemplate_serviceescalation *this_serviceescalation) {
6447 	char *temp_ptr = NULL;
6448 	char *template_names = NULL;
6449 	char *template_name_ptr = NULL;
6450 	xodtemplate_serviceescalation *template_serviceescalation = NULL;
6451 
6452 	/* return if this serviceescalation has already been resolved */
6453 	if(this_serviceescalation->has_been_resolved == TRUE)
6454 		return OK;
6455 
6456 	/* set the resolved flag */
6457 	this_serviceescalation->has_been_resolved = TRUE;
6458 
6459 	/* return if we have no template */
6460 	if(this_serviceescalation->template == NULL)
6461 		return OK;
6462 
6463 	if((template_names = (char *)strdup(this_serviceescalation->template)) == NULL)
6464 		return ERROR;
6465 
6466 	/* apply all templates */
6467 	template_name_ptr = template_names;
6468 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
6469 
6470 		template_serviceescalation = xodtemplate_find_serviceescalation(temp_ptr);
6471 		if(template_serviceescalation == NULL) {
6472 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in service escalation definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_serviceescalation->_config_file), this_serviceescalation->_start_line);
6473 			my_free(template_names);
6474 			return ERROR;
6475 			}
6476 
6477 		/* resolve the template serviceescalation... */
6478 		xodtemplate_resolve_serviceescalation(template_serviceescalation);
6479 
6480 		/* apply missing properties from template serviceescalation... */
6481 		xodtemplate_get_inherited_string(&template_serviceescalation->have_servicegroup_name, &template_serviceescalation->servicegroup_name, &this_serviceescalation->have_servicegroup_name, &this_serviceescalation->servicegroup_name);
6482 		xodtemplate_get_inherited_string(&template_serviceescalation->have_hostgroup_name, &template_serviceescalation->hostgroup_name, &this_serviceescalation->have_hostgroup_name, &this_serviceescalation->hostgroup_name);
6483 		xodtemplate_get_inherited_string(&template_serviceescalation->have_host_name, &template_serviceescalation->host_name, &this_serviceescalation->have_host_name, &this_serviceescalation->host_name);
6484 		xodtemplate_get_inherited_string(&template_serviceescalation->have_service_description, &template_serviceescalation->service_description, &this_serviceescalation->have_service_description, &this_serviceescalation->service_description);
6485 		xodtemplate_get_inherited_string(&template_serviceescalation->have_contact_groups, &template_serviceescalation->contact_groups, &this_serviceescalation->have_contact_groups, &this_serviceescalation->contact_groups);
6486 		xodtemplate_get_inherited_string(&template_serviceescalation->have_contacts, &template_serviceescalation->contacts, &this_serviceescalation->have_contacts, &this_serviceescalation->contacts);
6487 
6488 		if(this_serviceescalation->have_escalation_period == FALSE && template_serviceescalation->have_escalation_period == TRUE) {
6489 			if(this_serviceescalation->escalation_period == NULL && template_serviceescalation->escalation_period != NULL)
6490 				this_serviceescalation->escalation_period = (char *)strdup(template_serviceescalation->escalation_period);
6491 			this_serviceescalation->have_escalation_period = TRUE;
6492 			}
6493 		if(this_serviceescalation->have_first_notification == FALSE && template_serviceescalation->have_first_notification == TRUE) {
6494 			this_serviceescalation->first_notification = template_serviceescalation->first_notification;
6495 			this_serviceescalation->have_first_notification = TRUE;
6496 			}
6497 		if(this_serviceescalation->have_last_notification == FALSE && template_serviceescalation->have_last_notification == TRUE) {
6498 			this_serviceescalation->last_notification = template_serviceescalation->last_notification;
6499 			this_serviceescalation->have_last_notification = TRUE;
6500 			}
6501 		if(this_serviceescalation->have_notification_interval == FALSE && template_serviceescalation->have_notification_interval == TRUE) {
6502 			this_serviceescalation->notification_interval = template_serviceescalation->notification_interval;
6503 			this_serviceescalation->have_notification_interval = TRUE;
6504 			}
6505 		if(this_serviceescalation->have_escalation_options == FALSE && template_serviceescalation->have_escalation_options == TRUE) {
6506 			this_serviceescalation->escalate_on_warning = template_serviceescalation->escalate_on_warning;
6507 			this_serviceescalation->escalate_on_unknown = template_serviceescalation->escalate_on_unknown;
6508 			this_serviceescalation->escalate_on_critical = template_serviceescalation->escalate_on_critical;
6509 			this_serviceescalation->escalate_on_recovery = template_serviceescalation->escalate_on_recovery;
6510 			this_serviceescalation->have_escalation_options = TRUE;
6511 			}
6512 		}
6513 
6514 	my_free(template_names);
6515 
6516 	return OK;
6517 	}
6518 
6519 
6520 
6521 /* resolves a contact object */
xodtemplate_resolve_contact(xodtemplate_contact * this_contact)6522 int xodtemplate_resolve_contact(xodtemplate_contact *this_contact) {
6523 	char *temp_ptr = NULL;
6524 	char *template_names = NULL;
6525 	char *template_name_ptr = NULL;
6526 	xodtemplate_contact *template_contact = NULL;
6527 	xodtemplate_customvariablesmember *this_customvariablesmember = NULL;
6528 	xodtemplate_customvariablesmember *temp_customvariablesmember = NULL;
6529 	int x;
6530 
6531 	/* return if this contact has already been resolved */
6532 	if(this_contact->has_been_resolved == TRUE)
6533 		return OK;
6534 
6535 	/* set the resolved flag */
6536 	this_contact->has_been_resolved = TRUE;
6537 
6538 	/* return if we have no template */
6539 	if(this_contact->template == NULL)
6540 		return OK;
6541 
6542 	if((template_names = (char *)strdup(this_contact->template)) == NULL)
6543 		return ERROR;
6544 
6545 	/* apply all templates */
6546 	template_name_ptr = template_names;
6547 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
6548 
6549 		template_contact = xodtemplate_find_contact(temp_ptr);
6550 		if(template_contact == NULL) {
6551 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in contact definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_contact->_config_file), this_contact->_start_line);
6552 			my_free(template_names);
6553 			return ERROR;
6554 			}
6555 
6556 		/* resolve the template contact... */
6557 		xodtemplate_resolve_contact(template_contact);
6558 
6559 		/* apply missing properties from template contact... */
6560 		if(this_contact->contact_name == NULL && template_contact->contact_name != NULL)
6561 			this_contact->contact_name = (char *)strdup(template_contact->contact_name);
6562 		if(this_contact->alias == NULL && template_contact->alias != NULL)
6563 			this_contact->alias = (char *)strdup(template_contact->alias);
6564 
6565 		if(this_contact->have_email == FALSE && template_contact->have_email == TRUE) {
6566 			if(this_contact->email == NULL && template_contact->email != NULL)
6567 				this_contact->email = (char *)strdup(template_contact->email);
6568 			this_contact->have_email = TRUE;
6569 			}
6570 		if(this_contact->have_pager == FALSE && template_contact->have_pager == TRUE) {
6571 			if(this_contact->pager == NULL && template_contact->pager != NULL)
6572 				this_contact->pager = (char *)strdup(template_contact->pager);
6573 			this_contact->have_pager = TRUE;
6574 			}
6575 		for(x = 0; x < MAX_XODTEMPLATE_CONTACT_ADDRESSES; x++) {
6576 			if(this_contact->have_address[x] == FALSE && template_contact->have_address[x] == TRUE) {
6577 				if(this_contact->address[x] == NULL && template_contact->address[x] != NULL)
6578 					this_contact->address[x] = (char *)strdup(template_contact->address[x]);
6579 				this_contact->have_address[x] = TRUE;
6580 				}
6581 			}
6582 
6583 		xodtemplate_get_inherited_string(&template_contact->have_contact_groups, &template_contact->contact_groups, &this_contact->have_contact_groups, &this_contact->contact_groups);
6584 		xodtemplate_get_inherited_string(&template_contact->have_host_notification_commands, &template_contact->host_notification_commands, &this_contact->have_host_notification_commands, &this_contact->host_notification_commands);
6585 		xodtemplate_get_inherited_string(&template_contact->have_service_notification_commands, &template_contact->service_notification_commands, &this_contact->have_service_notification_commands, &this_contact->service_notification_commands);
6586 
6587 		if(this_contact->have_host_notification_period == FALSE && template_contact->have_host_notification_period == TRUE) {
6588 			if(this_contact->host_notification_period == NULL && template_contact->host_notification_period != NULL)
6589 				this_contact->host_notification_period = (char *)strdup(template_contact->host_notification_period);
6590 			this_contact->have_host_notification_period = TRUE;
6591 			}
6592 		if(this_contact->have_service_notification_period == FALSE && template_contact->have_service_notification_period == TRUE) {
6593 			if(this_contact->service_notification_period == NULL && template_contact->service_notification_period != NULL)
6594 				this_contact->service_notification_period = (char *)strdup(template_contact->service_notification_period);
6595 			this_contact->have_service_notification_period = TRUE;
6596 			}
6597 		if(this_contact->have_host_notification_options == FALSE && template_contact->have_host_notification_options == TRUE) {
6598 			this_contact->notify_on_host_down = template_contact->notify_on_host_down;
6599 			this_contact->notify_on_host_unreachable = template_contact->notify_on_host_unreachable;
6600 			this_contact->notify_on_host_recovery = template_contact->notify_on_host_recovery;
6601 			this_contact->notify_on_host_flapping = template_contact->notify_on_host_flapping;
6602 			this_contact->notify_on_host_downtime = template_contact->notify_on_host_downtime;
6603 			this_contact->have_host_notification_options = TRUE;
6604 			}
6605 		if(this_contact->have_service_notification_options == FALSE && template_contact->have_service_notification_options == TRUE) {
6606 			this_contact->notify_on_service_unknown = template_contact->notify_on_service_unknown;
6607 			this_contact->notify_on_service_warning = template_contact->notify_on_service_warning;
6608 			this_contact->notify_on_service_critical = template_contact->notify_on_service_critical;
6609 			this_contact->notify_on_service_recovery = template_contact->notify_on_service_recovery;
6610 			this_contact->notify_on_service_flapping = template_contact->notify_on_service_flapping;
6611 			this_contact->notify_on_service_downtime = template_contact->notify_on_service_downtime;
6612 			this_contact->have_service_notification_options = TRUE;
6613 			}
6614 		if(this_contact->have_host_notifications_enabled == FALSE && template_contact->have_host_notifications_enabled == TRUE) {
6615 			this_contact->host_notifications_enabled = template_contact->host_notifications_enabled;
6616 			this_contact->have_host_notifications_enabled = TRUE;
6617 			}
6618 		if(this_contact->have_service_notifications_enabled == FALSE && template_contact->have_service_notifications_enabled == TRUE) {
6619 			this_contact->service_notifications_enabled = template_contact->service_notifications_enabled;
6620 			this_contact->have_service_notifications_enabled = TRUE;
6621 			}
6622 		if(this_contact->have_can_submit_commands == FALSE && template_contact->have_can_submit_commands == TRUE) {
6623 			this_contact->can_submit_commands = template_contact->can_submit_commands;
6624 			this_contact->have_can_submit_commands = TRUE;
6625 			}
6626 		if(this_contact->have_retain_status_information == FALSE && template_contact->have_retain_status_information == TRUE) {
6627 			this_contact->retain_status_information = template_contact->retain_status_information;
6628 			this_contact->have_retain_status_information = TRUE;
6629 			}
6630 		if(this_contact->have_retain_nonstatus_information == FALSE && template_contact->have_retain_nonstatus_information == TRUE) {
6631 			this_contact->retain_nonstatus_information = template_contact->retain_nonstatus_information;
6632 			this_contact->have_retain_nonstatus_information = TRUE;
6633 			}
6634 
6635 		/* apply missing custom variables from template contact... */
6636 		for(temp_customvariablesmember = template_contact->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) {
6637 
6638 			/* see if this host has a variable by the same name */
6639 			for(this_customvariablesmember = this_contact->custom_variables; this_customvariablesmember != NULL; this_customvariablesmember = this_customvariablesmember->next) {
6640 				if(!strcmp(temp_customvariablesmember->variable_name, this_customvariablesmember->variable_name))
6641 					break;
6642 				}
6643 
6644 			/* we didn't find the same variable name, so add a new custom variable */
6645 			if(this_customvariablesmember == NULL)
6646 				xodtemplate_add_custom_variable_to_contact(this_contact, temp_customvariablesmember->variable_name, temp_customvariablesmember->variable_value);
6647 			}
6648 		}
6649 
6650 	my_free(template_names);
6651 
6652 	return OK;
6653 	}
6654 
6655 
6656 
6657 /* resolves a host object */
xodtemplate_resolve_host(xodtemplate_host * this_host)6658 int xodtemplate_resolve_host(xodtemplate_host *this_host) {
6659 	char *temp_ptr = NULL;
6660 	char *template_names = NULL;
6661 	char *template_name_ptr = NULL;
6662 	xodtemplate_host *template_host = NULL;
6663 	xodtemplate_customvariablesmember *this_customvariablesmember = NULL;
6664 	xodtemplate_customvariablesmember *temp_customvariablesmember = NULL;
6665 
6666 	/* return if this host has already been resolved */
6667 	if(this_host->has_been_resolved == TRUE)
6668 		return OK;
6669 
6670 	/* set the resolved flag */
6671 	this_host->has_been_resolved = TRUE;
6672 
6673 	/* return if we have no template */
6674 	if(this_host->template == NULL)
6675 		return OK;
6676 
6677 	if((template_names = (char *)strdup(this_host->template)) == NULL)
6678 		return ERROR;
6679 
6680 	/* apply all templates */
6681 	template_name_ptr = template_names;
6682 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
6683 
6684 		template_host = xodtemplate_find_host(temp_ptr);
6685 		if(template_host == NULL) {
6686 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in host definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_host->_config_file), this_host->_start_line);
6687 			my_free(template_names);
6688 			return ERROR;
6689 			}
6690 
6691 		/* resolve the template host... */
6692 		xodtemplate_resolve_host(template_host);
6693 
6694 		/* apply missing properties from template host... */
6695 		if(this_host->host_name == NULL && template_host->host_name != NULL)
6696 			this_host->host_name = (char *)strdup(template_host->host_name);
6697 		if(this_host->have_display_name == FALSE && template_host->have_display_name == TRUE) {
6698 			if(this_host->display_name == NULL && template_host->display_name != NULL)
6699 				this_host->display_name = (char *)strdup(template_host->display_name);
6700 			this_host->have_display_name = TRUE;
6701 			}
6702 		if(this_host->alias == NULL && template_host->alias != NULL)
6703 			this_host->alias = (char *)strdup(template_host->alias);
6704 		if(this_host->address == NULL && template_host->address != NULL)
6705 			this_host->address = (char *)strdup(template_host->address);
6706 
6707 		xodtemplate_get_inherited_string(&template_host->have_parents, &template_host->parents, &this_host->have_parents, &this_host->parents);
6708 		xodtemplate_get_inherited_string(&template_host->have_host_groups, &template_host->host_groups, &this_host->have_host_groups, &this_host->host_groups);
6709 		xodtemplate_get_inherited_string(&template_host->have_contact_groups, &template_host->contact_groups, &this_host->have_contact_groups, &this_host->contact_groups);
6710 		xodtemplate_get_inherited_string(&template_host->have_contacts, &template_host->contacts, &this_host->have_contacts, &this_host->contacts);
6711 
6712 		if(this_host->have_check_command == FALSE && template_host->have_check_command == TRUE) {
6713 			if(this_host->check_command == NULL && template_host->check_command != NULL)
6714 				this_host->check_command = (char *)strdup(template_host->check_command);
6715 			this_host->have_check_command = TRUE;
6716 			}
6717 		if(this_host->have_check_period == FALSE && template_host->have_check_period == TRUE) {
6718 			if(this_host->check_period == NULL && template_host->check_period != NULL)
6719 				this_host->check_period = (char *)strdup(template_host->check_period);
6720 			this_host->have_check_period = TRUE;
6721 			}
6722 		if(this_host->have_event_handler == FALSE && template_host->have_event_handler == TRUE) {
6723 			if(this_host->event_handler == NULL && template_host->event_handler != NULL)
6724 				this_host->event_handler = (char *)strdup(template_host->event_handler);
6725 			this_host->have_event_handler = TRUE;
6726 			}
6727 		if(this_host->have_notification_period == FALSE && template_host->have_notification_period == TRUE) {
6728 			if(this_host->notification_period == NULL && template_host->notification_period != NULL)
6729 				this_host->notification_period = (char *)strdup(template_host->notification_period);
6730 			this_host->have_notification_period = TRUE;
6731 			}
6732 		if(this_host->have_failure_prediction_options == FALSE && template_host->have_failure_prediction_options == TRUE) {
6733 			if(this_host->failure_prediction_options == NULL && template_host->failure_prediction_options != NULL)
6734 				this_host->failure_prediction_options = (char *)strdup(template_host->failure_prediction_options);
6735 			this_host->have_failure_prediction_options = TRUE;
6736 			}
6737 		if(this_host->have_notes == FALSE && template_host->have_notes == TRUE) {
6738 			if(this_host->notes == NULL && template_host->notes != NULL)
6739 				this_host->notes = (char *)strdup(template_host->notes);
6740 			this_host->have_notes = TRUE;
6741 			}
6742 		if(this_host->have_notes_url == FALSE && template_host->have_notes_url == TRUE) {
6743 			if(this_host->notes_url == NULL && template_host->notes_url != NULL)
6744 				this_host->notes_url = (char *)strdup(template_host->notes_url);
6745 			this_host->have_notes_url = TRUE;
6746 			}
6747 		if(this_host->have_action_url == FALSE && template_host->have_action_url == TRUE) {
6748 			if(this_host->action_url == NULL && template_host->action_url != NULL)
6749 				this_host->action_url = (char *)strdup(template_host->action_url);
6750 			this_host->have_action_url = TRUE;
6751 			}
6752 		if(this_host->have_icon_image == FALSE && template_host->have_icon_image == TRUE) {
6753 			if(this_host->icon_image == NULL && template_host->icon_image != NULL)
6754 				this_host->icon_image = (char *)strdup(template_host->icon_image);
6755 			this_host->have_icon_image = TRUE;
6756 			}
6757 		if(this_host->have_icon_image_alt == FALSE && template_host->have_icon_image_alt == TRUE) {
6758 			if(this_host->icon_image_alt == NULL && template_host->icon_image_alt != NULL)
6759 				this_host->icon_image_alt = (char *)strdup(template_host->icon_image_alt);
6760 			this_host->have_icon_image_alt = TRUE;
6761 			}
6762 		if(this_host->have_vrml_image == FALSE && template_host->have_vrml_image == TRUE) {
6763 			if(this_host->vrml_image == NULL && template_host->vrml_image != NULL)
6764 				this_host->vrml_image = (char *)strdup(template_host->vrml_image);
6765 			this_host->have_vrml_image = TRUE;
6766 			}
6767 		if(this_host->have_statusmap_image == FALSE && template_host->have_statusmap_image == TRUE) {
6768 			if(this_host->statusmap_image == NULL && template_host->statusmap_image != NULL)
6769 				this_host->statusmap_image = (char *)strdup(template_host->statusmap_image);
6770 			this_host->have_statusmap_image = TRUE;
6771 			}
6772 		if(this_host->have_initial_state == FALSE && template_host->have_initial_state == TRUE) {
6773 			this_host->initial_state = template_host->initial_state;
6774 			this_host->have_initial_state = TRUE;
6775 			}
6776 		if(this_host->have_check_interval == FALSE && template_host->have_check_interval == TRUE) {
6777 			this_host->check_interval = template_host->check_interval;
6778 			this_host->have_check_interval = TRUE;
6779 			}
6780 		if(this_host->have_retry_interval == FALSE && template_host->have_retry_interval == TRUE) {
6781 			this_host->retry_interval = template_host->retry_interval;
6782 			this_host->have_retry_interval = TRUE;
6783 			}
6784 		if(this_host->have_max_check_attempts == FALSE && template_host->have_max_check_attempts == TRUE) {
6785 			this_host->max_check_attempts = template_host->max_check_attempts;
6786 			this_host->have_max_check_attempts = TRUE;
6787 			}
6788 		if(this_host->have_active_checks_enabled == FALSE && template_host->have_active_checks_enabled == TRUE) {
6789 			this_host->active_checks_enabled = template_host->active_checks_enabled;
6790 			this_host->have_active_checks_enabled = TRUE;
6791 			}
6792 		if(this_host->have_passive_checks_enabled == FALSE && template_host->have_passive_checks_enabled == TRUE) {
6793 			this_host->passive_checks_enabled = template_host->passive_checks_enabled;
6794 			this_host->have_passive_checks_enabled = TRUE;
6795 			}
6796 		if(this_host->have_obsess_over_host == FALSE && template_host->have_obsess_over_host == TRUE) {
6797 			this_host->obsess_over_host = template_host->obsess_over_host;
6798 			this_host->have_obsess_over_host = TRUE;
6799 			}
6800 		if(this_host->have_event_handler_enabled == FALSE && template_host->have_event_handler_enabled == TRUE) {
6801 			this_host->event_handler_enabled = template_host->event_handler_enabled;
6802 			this_host->have_event_handler_enabled = TRUE;
6803 			}
6804 		if(this_host->have_check_freshness == FALSE && template_host->have_check_freshness == TRUE) {
6805 			this_host->check_freshness = template_host->check_freshness;
6806 			this_host->have_check_freshness = TRUE;
6807 			}
6808 		if(this_host->have_freshness_threshold == FALSE && template_host->have_freshness_threshold == TRUE) {
6809 			this_host->freshness_threshold = template_host->freshness_threshold;
6810 			this_host->have_freshness_threshold = TRUE;
6811 			}
6812 		if(this_host->have_low_flap_threshold == FALSE && template_host->have_low_flap_threshold == TRUE) {
6813 			this_host->low_flap_threshold = template_host->low_flap_threshold;
6814 			this_host->have_low_flap_threshold = TRUE;
6815 			}
6816 		if(this_host->have_high_flap_threshold == FALSE && template_host->have_high_flap_threshold == TRUE) {
6817 			this_host->high_flap_threshold = template_host->high_flap_threshold;
6818 			this_host->have_high_flap_threshold = TRUE;
6819 			}
6820 		if(this_host->have_flap_detection_enabled == FALSE && template_host->have_flap_detection_enabled == TRUE) {
6821 			this_host->flap_detection_enabled = template_host->flap_detection_enabled;
6822 			this_host->have_flap_detection_enabled = TRUE;
6823 			}
6824 		if(this_host->have_flap_detection_options == FALSE && template_host->have_flap_detection_options == TRUE) {
6825 			this_host->flap_detection_on_up = template_host->flap_detection_on_up;
6826 			this_host->flap_detection_on_down = template_host->flap_detection_on_down;
6827 			this_host->flap_detection_on_unreachable = template_host->flap_detection_on_unreachable;
6828 			this_host->have_flap_detection_options = TRUE;
6829 			}
6830 		if(this_host->have_notification_options == FALSE && template_host->have_notification_options == TRUE) {
6831 			this_host->notify_on_down = template_host->notify_on_down;
6832 			this_host->notify_on_unreachable = template_host->notify_on_unreachable;
6833 			this_host->notify_on_recovery = template_host->notify_on_recovery;
6834 			this_host->notify_on_flapping = template_host->notify_on_flapping;
6835 			this_host->notify_on_downtime = template_host->notify_on_downtime;
6836 			this_host->have_notification_options = TRUE;
6837 			}
6838 		if(this_host->have_notifications_enabled == FALSE && template_host->have_notifications_enabled == TRUE) {
6839 			this_host->notifications_enabled = template_host->notifications_enabled;
6840 			this_host->have_notifications_enabled = TRUE;
6841 			}
6842 		if(this_host->have_notification_interval == FALSE && template_host->have_notification_interval == TRUE) {
6843 			this_host->notification_interval = template_host->notification_interval;
6844 			this_host->have_notification_interval = TRUE;
6845 			}
6846 		if(this_host->have_first_notification_delay == FALSE && template_host->have_first_notification_delay == TRUE) {
6847 			this_host->first_notification_delay = template_host->first_notification_delay;
6848 			this_host->have_first_notification_delay = TRUE;
6849 			}
6850 		if(this_host->have_stalking_options == FALSE && template_host->have_stalking_options == TRUE) {
6851 			this_host->stalk_on_up = template_host->stalk_on_up;
6852 			this_host->stalk_on_down = template_host->stalk_on_down;
6853 			this_host->stalk_on_unreachable = template_host->stalk_on_unreachable;
6854 			this_host->have_stalking_options = TRUE;
6855 			}
6856 		if(this_host->have_process_perf_data == FALSE && template_host->have_process_perf_data == TRUE) {
6857 			this_host->process_perf_data = template_host->process_perf_data;
6858 			this_host->have_process_perf_data = TRUE;
6859 			}
6860 		if(this_host->have_failure_prediction_enabled == FALSE && template_host->have_failure_prediction_enabled == TRUE) {
6861 			this_host->failure_prediction_enabled = template_host->failure_prediction_enabled;
6862 			this_host->have_failure_prediction_enabled = TRUE;
6863 			}
6864 		if(this_host->have_2d_coords == FALSE && template_host->have_2d_coords == TRUE) {
6865 			this_host->x_2d = template_host->x_2d;
6866 			this_host->y_2d = template_host->y_2d;
6867 			this_host->have_2d_coords = TRUE;
6868 			}
6869 		if(this_host->have_3d_coords == FALSE && template_host->have_3d_coords == TRUE) {
6870 			this_host->x_3d = template_host->x_3d;
6871 			this_host->y_3d = template_host->y_3d;
6872 			this_host->z_3d = template_host->z_3d;
6873 			this_host->have_3d_coords = TRUE;
6874 			}
6875 		if(this_host->have_retain_status_information == FALSE && template_host->have_retain_status_information == TRUE) {
6876 			this_host->retain_status_information = template_host->retain_status_information;
6877 			this_host->have_retain_status_information = TRUE;
6878 			}
6879 		if(this_host->have_retain_nonstatus_information == FALSE && template_host->have_retain_nonstatus_information == TRUE) {
6880 			this_host->retain_nonstatus_information = template_host->retain_nonstatus_information;
6881 			this_host->have_retain_nonstatus_information = TRUE;
6882 			}
6883 
6884 		/* apply missing custom variables from template host... */
6885 		for(temp_customvariablesmember = template_host->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) {
6886 
6887 			/* see if this host has a variable by the same name */
6888 			for(this_customvariablesmember = this_host->custom_variables; this_customvariablesmember != NULL; this_customvariablesmember = this_customvariablesmember->next) {
6889 				if(!strcmp(temp_customvariablesmember->variable_name, this_customvariablesmember->variable_name))
6890 					break;
6891 				}
6892 
6893 			/* we didn't find the same variable name, so add a new custom variable */
6894 			if(this_customvariablesmember == NULL)
6895 				xodtemplate_add_custom_variable_to_host(this_host, temp_customvariablesmember->variable_name, temp_customvariablesmember->variable_value);
6896 			}
6897 		}
6898 
6899 	my_free(template_names);
6900 
6901 	return OK;
6902 	}
6903 
6904 
6905 
6906 /* resolves a service object */
xodtemplate_resolve_service(xodtemplate_service * this_service)6907 int xodtemplate_resolve_service(xodtemplate_service *this_service) {
6908 	char *temp_ptr = NULL;
6909 	char *template_names = NULL;
6910 	char *template_name_ptr = NULL;
6911 	xodtemplate_service *template_service = NULL;
6912 	xodtemplate_customvariablesmember *this_customvariablesmember = NULL;
6913 	xodtemplate_customvariablesmember *temp_customvariablesmember = NULL;
6914 
6915 	/* return if this service has already been resolved */
6916 	if(this_service->has_been_resolved == TRUE)
6917 		return OK;
6918 
6919 	/* set the resolved flag */
6920 	this_service->has_been_resolved = TRUE;
6921 
6922 	/* return if we have no template */
6923 	if(this_service->template == NULL)
6924 		return OK;
6925 
6926 	if((template_names = (char *)strdup(this_service->template)) == NULL)
6927 		return ERROR;
6928 
6929 	/* apply all templates */
6930 	template_name_ptr = template_names;
6931 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
6932 
6933 		template_service = xodtemplate_find_service(temp_ptr);
6934 		if(template_service == NULL) {
6935 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in service definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_service->_config_file), this_service->_start_line);
6936 			my_free(template_names);
6937 			return ERROR;
6938 			}
6939 
6940 		/* resolve the template service... */
6941 		xodtemplate_resolve_service(template_service);
6942 
6943 		/* apply missing properties from template service... */
6944 		if(this_service->have_service_description == FALSE && template_service->have_service_description == TRUE) {
6945 			if(this_service->service_description == NULL && template_service->service_description != NULL)
6946 				this_service->service_description = (char *)strdup(template_service->service_description);
6947 			this_service->have_service_description = TRUE;
6948 			}
6949 		if(this_service->have_display_name == FALSE && template_service->have_display_name == TRUE) {
6950 			if(this_service->display_name == NULL && template_service->display_name != NULL)
6951 				this_service->display_name = (char *)strdup(template_service->display_name);
6952 			this_service->have_display_name = TRUE;
6953 			}
6954 
6955 		xodtemplate_get_inherited_string(&template_service->have_host_name, &template_service->host_name, &this_service->have_host_name, &this_service->host_name);
6956 		xodtemplate_get_inherited_string(&template_service->have_hostgroup_name, &template_service->hostgroup_name, &this_service->have_hostgroup_name, &this_service->hostgroup_name);
6957 		xodtemplate_get_inherited_string(&template_service->have_service_groups, &template_service->service_groups, &this_service->have_service_groups, &this_service->service_groups);
6958 		xodtemplate_get_inherited_string(&template_service->have_contact_groups, &template_service->contact_groups, &this_service->have_contact_groups, &this_service->contact_groups);
6959 		xodtemplate_get_inherited_string(&template_service->have_contacts, &template_service->contacts, &this_service->have_contacts, &this_service->contacts);
6960 
6961 		if(template_service->have_check_command == TRUE) {
6962 			if(template_service->have_important_check_command == TRUE) {
6963 				my_free(this_service->check_command);
6964 				this_service->have_check_command = FALSE;
6965 				}
6966 			if(this_service->have_check_command == FALSE) {
6967 				if(this_service->check_command == NULL && template_service->check_command != NULL)
6968 					this_service->check_command = (char *)strdup(template_service->check_command);
6969 				this_service->have_check_command = TRUE;
6970 				}
6971 			}
6972 		if(this_service->have_check_period == FALSE && template_service->have_check_period == TRUE) {
6973 			if(this_service->check_period == NULL && template_service->check_period != NULL)
6974 				this_service->check_period = (char *)strdup(template_service->check_period);
6975 			this_service->have_check_period = TRUE;
6976 			}
6977 		if(this_service->have_event_handler == FALSE && template_service->have_event_handler == TRUE) {
6978 			if(this_service->event_handler == NULL && template_service->event_handler != NULL)
6979 				this_service->event_handler = (char *)strdup(template_service->event_handler);
6980 			this_service->have_event_handler = TRUE;
6981 			}
6982 		if(this_service->have_notification_period == FALSE && template_service->have_notification_period == TRUE) {
6983 			if(this_service->notification_period == NULL && template_service->notification_period != NULL)
6984 				this_service->notification_period = (char *)strdup(template_service->notification_period);
6985 			this_service->have_notification_period = TRUE;
6986 			}
6987 		if(this_service->have_failure_prediction_options == FALSE && template_service->have_failure_prediction_options == TRUE) {
6988 			if(this_service->failure_prediction_options == NULL && template_service->failure_prediction_options != NULL)
6989 				this_service->failure_prediction_options = (char *)strdup(template_service->failure_prediction_options);
6990 			this_service->have_failure_prediction_options = TRUE;
6991 			}
6992 		if(this_service->have_notes == FALSE && template_service->have_notes == TRUE) {
6993 			if(this_service->notes == NULL && template_service->notes != NULL)
6994 				this_service->notes = (char *)strdup(template_service->notes);
6995 			this_service->have_notes = TRUE;
6996 			}
6997 		if(this_service->have_notes_url == FALSE && template_service->have_notes_url == TRUE) {
6998 			if(this_service->notes_url == NULL && template_service->notes_url != NULL)
6999 				this_service->notes_url = (char *)strdup(template_service->notes_url);
7000 			this_service->have_notes_url = TRUE;
7001 			}
7002 		if(this_service->have_action_url == FALSE && template_service->have_action_url == TRUE) {
7003 			if(this_service->action_url == NULL && template_service->action_url != NULL)
7004 				this_service->action_url = (char *)strdup(template_service->action_url);
7005 			this_service->have_action_url = TRUE;
7006 			}
7007 		if(this_service->have_icon_image == FALSE && template_service->have_icon_image == TRUE) {
7008 			if(this_service->icon_image == NULL && template_service->icon_image != NULL)
7009 				this_service->icon_image = (char *)strdup(template_service->icon_image);
7010 			this_service->have_icon_image = TRUE;
7011 			}
7012 		if(this_service->have_icon_image_alt == FALSE && template_service->have_icon_image_alt == TRUE) {
7013 			if(this_service->icon_image_alt == NULL && template_service->icon_image_alt != NULL)
7014 				this_service->icon_image_alt = (char *)strdup(template_service->icon_image_alt);
7015 			this_service->have_icon_image_alt = TRUE;
7016 			}
7017 		if(this_service->have_initial_state == FALSE && template_service->have_initial_state == TRUE) {
7018 			this_service->initial_state = template_service->initial_state;
7019 			this_service->have_initial_state = TRUE;
7020 			}
7021 		if(this_service->have_max_check_attempts == FALSE && template_service->have_max_check_attempts == TRUE) {
7022 			this_service->max_check_attempts = template_service->max_check_attempts;
7023 			this_service->have_max_check_attempts = TRUE;
7024 			}
7025 		if(this_service->have_check_interval == FALSE && template_service->have_check_interval == TRUE) {
7026 			this_service->check_interval = template_service->check_interval;
7027 			this_service->have_check_interval = TRUE;
7028 			}
7029 		if(this_service->have_retry_interval == FALSE && template_service->have_retry_interval == TRUE) {
7030 			this_service->retry_interval = template_service->retry_interval;
7031 			this_service->have_retry_interval = TRUE;
7032 			}
7033 		if(this_service->have_active_checks_enabled == FALSE && template_service->have_active_checks_enabled == TRUE) {
7034 			this_service->active_checks_enabled = template_service->active_checks_enabled;
7035 			this_service->have_active_checks_enabled = TRUE;
7036 			}
7037 		if(this_service->have_passive_checks_enabled == FALSE && template_service->have_passive_checks_enabled == TRUE) {
7038 			this_service->passive_checks_enabled = template_service->passive_checks_enabled;
7039 			this_service->have_passive_checks_enabled = TRUE;
7040 			}
7041 		if(this_service->have_parallelize_check == FALSE && template_service->have_parallelize_check == TRUE) {
7042 			this_service->parallelize_check = template_service->parallelize_check;
7043 			this_service->have_parallelize_check = TRUE;
7044 			}
7045 		if(this_service->have_is_volatile == FALSE && template_service->have_is_volatile == TRUE) {
7046 			this_service->is_volatile = template_service->is_volatile;
7047 			this_service->have_is_volatile = TRUE;
7048 			}
7049 		if(this_service->have_obsess_over_service == FALSE && template_service->have_obsess_over_service == TRUE) {
7050 			this_service->obsess_over_service = template_service->obsess_over_service;
7051 			this_service->have_obsess_over_service = TRUE;
7052 			}
7053 		if(this_service->have_event_handler_enabled == FALSE && template_service->have_event_handler_enabled == TRUE) {
7054 			this_service->event_handler_enabled = template_service->event_handler_enabled;
7055 			this_service->have_event_handler_enabled = TRUE;
7056 			}
7057 		if(this_service->have_check_freshness == FALSE && template_service->have_check_freshness == TRUE) {
7058 			this_service->check_freshness = template_service->check_freshness;
7059 			this_service->have_check_freshness = TRUE;
7060 			}
7061 		if(this_service->have_freshness_threshold == FALSE && template_service->have_freshness_threshold == TRUE) {
7062 			this_service->freshness_threshold = template_service->freshness_threshold;
7063 			this_service->have_freshness_threshold = TRUE;
7064 			}
7065 		if(this_service->have_low_flap_threshold == FALSE && template_service->have_low_flap_threshold == TRUE) {
7066 			this_service->low_flap_threshold = template_service->low_flap_threshold;
7067 			this_service->have_low_flap_threshold = TRUE;
7068 			}
7069 		if(this_service->have_high_flap_threshold == FALSE && template_service->have_high_flap_threshold == TRUE) {
7070 			this_service->high_flap_threshold = template_service->high_flap_threshold;
7071 			this_service->have_high_flap_threshold = TRUE;
7072 			}
7073 		if(this_service->have_flap_detection_enabled == FALSE && template_service->have_flap_detection_enabled == TRUE) {
7074 			this_service->flap_detection_enabled = template_service->flap_detection_enabled;
7075 			this_service->have_flap_detection_enabled = TRUE;
7076 			}
7077 		if(this_service->have_flap_detection_options == FALSE && template_service->have_flap_detection_options == TRUE) {
7078 			this_service->flap_detection_on_ok = template_service->flap_detection_on_ok;
7079 			this_service->flap_detection_on_unknown = template_service->flap_detection_on_unknown;
7080 			this_service->flap_detection_on_warning = template_service->flap_detection_on_warning;
7081 			this_service->flap_detection_on_critical = template_service->flap_detection_on_critical;
7082 			this_service->have_flap_detection_options = TRUE;
7083 			}
7084 		if(this_service->have_notification_options == FALSE && template_service->have_notification_options == TRUE) {
7085 			this_service->notify_on_unknown = template_service->notify_on_unknown;
7086 			this_service->notify_on_warning = template_service->notify_on_warning;
7087 			this_service->notify_on_critical = template_service->notify_on_critical;
7088 			this_service->notify_on_recovery = template_service->notify_on_recovery;
7089 			this_service->notify_on_flapping = template_service->notify_on_flapping;
7090 			this_service->notify_on_downtime = template_service->notify_on_downtime;
7091 			this_service->have_notification_options = TRUE;
7092 			}
7093 		if(this_service->have_notifications_enabled == FALSE && template_service->have_notifications_enabled == TRUE) {
7094 			this_service->notifications_enabled = template_service->notifications_enabled;
7095 			this_service->have_notifications_enabled = TRUE;
7096 			}
7097 		if(this_service->have_notification_interval == FALSE && template_service->have_notification_interval == TRUE) {
7098 			this_service->notification_interval = template_service->notification_interval;
7099 			this_service->have_notification_interval = TRUE;
7100 			}
7101 		if(this_service->have_first_notification_delay == FALSE && template_service->have_first_notification_delay == TRUE) {
7102 			this_service->first_notification_delay = template_service->first_notification_delay;
7103 			this_service->have_first_notification_delay = TRUE;
7104 			}
7105 		if(this_service->have_stalking_options == FALSE && template_service->have_stalking_options == TRUE) {
7106 			this_service->stalk_on_ok = template_service->stalk_on_ok;
7107 			this_service->stalk_on_unknown = template_service->stalk_on_unknown;
7108 			this_service->stalk_on_warning = template_service->stalk_on_warning;
7109 			this_service->stalk_on_critical = template_service->stalk_on_critical;
7110 			this_service->have_stalking_options = TRUE;
7111 			}
7112 		if(this_service->have_process_perf_data == FALSE && template_service->have_process_perf_data == TRUE) {
7113 			this_service->process_perf_data = template_service->process_perf_data;
7114 			this_service->have_process_perf_data = TRUE;
7115 			}
7116 		if(this_service->have_failure_prediction_enabled == FALSE && template_service->have_failure_prediction_enabled == TRUE) {
7117 			this_service->failure_prediction_enabled = template_service->failure_prediction_enabled;
7118 			this_service->have_failure_prediction_enabled = TRUE;
7119 			}
7120 		if(this_service->have_retain_status_information == FALSE && template_service->have_retain_status_information == TRUE) {
7121 			this_service->retain_status_information = template_service->retain_status_information;
7122 			this_service->have_retain_status_information = TRUE;
7123 			}
7124 		if(this_service->have_retain_nonstatus_information == FALSE && template_service->have_retain_nonstatus_information == TRUE) {
7125 			this_service->retain_nonstatus_information = template_service->retain_nonstatus_information;
7126 			this_service->have_retain_nonstatus_information = TRUE;
7127 			}
7128 
7129 		/* apply missing custom variables from template service... */
7130 		for(temp_customvariablesmember = template_service->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) {
7131 
7132 			/* see if this host has a variable by the same name */
7133 			for(this_customvariablesmember = this_service->custom_variables; this_customvariablesmember != NULL; this_customvariablesmember = this_customvariablesmember->next) {
7134 				if(!strcmp(temp_customvariablesmember->variable_name, this_customvariablesmember->variable_name))
7135 					break;
7136 				}
7137 
7138 			/* we didn't find the same variable name, so add a new custom variable */
7139 			if(this_customvariablesmember == NULL)
7140 				xodtemplate_add_custom_variable_to_service(this_service, temp_customvariablesmember->variable_name, temp_customvariablesmember->variable_value);
7141 			}
7142 		}
7143 
7144 	my_free(template_names);
7145 
7146 	return OK;
7147 	}
7148 
7149 
7150 /* resolves a hostdependency object */
xodtemplate_resolve_hostdependency(xodtemplate_hostdependency * this_hostdependency)7151 int xodtemplate_resolve_hostdependency(xodtemplate_hostdependency *this_hostdependency) {
7152 	char *temp_ptr = NULL;
7153 	char *template_names = NULL;
7154 	char *template_name_ptr = NULL;
7155 	xodtemplate_hostdependency *template_hostdependency = NULL;
7156 
7157 	/* return if this hostdependency has already been resolved */
7158 	if(this_hostdependency->has_been_resolved == TRUE)
7159 		return OK;
7160 
7161 	/* set the resolved flag */
7162 	this_hostdependency->has_been_resolved = TRUE;
7163 
7164 	/* return if we have no template */
7165 	if(this_hostdependency->template == NULL)
7166 		return OK;
7167 
7168 	if((template_names = (char *)strdup(this_hostdependency->template)) == NULL)
7169 		return ERROR;
7170 
7171 	/* apply all templates */
7172 	template_name_ptr = template_names;
7173 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
7174 
7175 		template_hostdependency = xodtemplate_find_hostdependency(temp_ptr);
7176 		if(template_hostdependency == NULL) {
7177 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in host dependency definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_hostdependency->_config_file), this_hostdependency->_start_line);
7178 			my_free(template_names);
7179 			return ERROR;
7180 			}
7181 
7182 		/* resolve the template hostdependency... */
7183 		xodtemplate_resolve_hostdependency(template_hostdependency);
7184 
7185 		/* apply missing properties from template hostdependency... */
7186 
7187 		xodtemplate_get_inherited_string(&template_hostdependency->have_host_name, &template_hostdependency->host_name, &this_hostdependency->have_host_name, &this_hostdependency->host_name);
7188 		xodtemplate_get_inherited_string(&template_hostdependency->have_dependent_host_name, &template_hostdependency->dependent_host_name, &this_hostdependency->have_dependent_host_name, &this_hostdependency->dependent_host_name);
7189 		xodtemplate_get_inherited_string(&template_hostdependency->have_hostgroup_name, &template_hostdependency->hostgroup_name, &this_hostdependency->have_hostgroup_name, &this_hostdependency->hostgroup_name);
7190 		xodtemplate_get_inherited_string(&template_hostdependency->have_dependent_hostgroup_name, &template_hostdependency->dependent_hostgroup_name, &this_hostdependency->have_dependent_hostgroup_name, &this_hostdependency->dependent_hostgroup_name);
7191 
7192 		if(this_hostdependency->have_dependency_period == FALSE && template_hostdependency->have_dependency_period == TRUE) {
7193 			if(this_hostdependency->dependency_period == NULL && template_hostdependency->dependency_period != NULL)
7194 				this_hostdependency->dependency_period = (char *)strdup(template_hostdependency->dependency_period);
7195 			this_hostdependency->have_dependency_period = TRUE;
7196 			}
7197 		if(this_hostdependency->have_inherits_parent == FALSE && template_hostdependency->have_inherits_parent == TRUE) {
7198 			this_hostdependency->inherits_parent = template_hostdependency->inherits_parent;
7199 			this_hostdependency->have_inherits_parent = TRUE;
7200 			}
7201 		if(this_hostdependency->have_execution_dependency_options == FALSE && template_hostdependency->have_execution_dependency_options == TRUE) {
7202 			this_hostdependency->fail_execute_on_up = template_hostdependency->fail_execute_on_up;
7203 			this_hostdependency->fail_execute_on_down = template_hostdependency->fail_execute_on_down;
7204 			this_hostdependency->fail_execute_on_unreachable = template_hostdependency->fail_execute_on_unreachable;
7205 			this_hostdependency->fail_execute_on_pending = template_hostdependency->fail_execute_on_pending;
7206 			this_hostdependency->have_execution_dependency_options = TRUE;
7207 			}
7208 		if(this_hostdependency->have_notification_dependency_options == FALSE && template_hostdependency->have_notification_dependency_options == TRUE) {
7209 			this_hostdependency->fail_notify_on_up = template_hostdependency->fail_notify_on_up;
7210 			this_hostdependency->fail_notify_on_down = template_hostdependency->fail_notify_on_down;
7211 			this_hostdependency->fail_notify_on_unreachable = template_hostdependency->fail_notify_on_unreachable;
7212 			this_hostdependency->fail_notify_on_pending = template_hostdependency->fail_notify_on_pending;
7213 			this_hostdependency->have_notification_dependency_options = TRUE;
7214 			}
7215 		}
7216 
7217 	my_free(template_names);
7218 
7219 	return OK;
7220 	}
7221 
7222 
7223 /* resolves a hostescalation object */
xodtemplate_resolve_hostescalation(xodtemplate_hostescalation * this_hostescalation)7224 int xodtemplate_resolve_hostescalation(xodtemplate_hostescalation *this_hostescalation) {
7225 	char *temp_ptr = NULL;
7226 	char *template_names = NULL;
7227 	char *template_name_ptr = NULL;
7228 	xodtemplate_hostescalation *template_hostescalation = NULL;
7229 
7230 	/* return if this hostescalation has already been resolved */
7231 	if(this_hostescalation->has_been_resolved == TRUE)
7232 		return OK;
7233 
7234 	/* set the resolved flag */
7235 	this_hostescalation->has_been_resolved = TRUE;
7236 
7237 	/* return if we have no template */
7238 	if(this_hostescalation->template == NULL)
7239 		return OK;
7240 
7241 	if((template_names = (char *)strdup(this_hostescalation->template)) == NULL)
7242 		return ERROR;
7243 
7244 	/* apply all templates */
7245 	template_name_ptr = template_names;
7246 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
7247 
7248 		template_hostescalation = xodtemplate_find_hostescalation(temp_ptr);
7249 		if(template_hostescalation == NULL) {
7250 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in host escalation definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_hostescalation->_config_file), this_hostescalation->_start_line);
7251 			my_free(template_names);
7252 			return ERROR;
7253 			}
7254 
7255 		/* resolve the template hostescalation... */
7256 		xodtemplate_resolve_hostescalation(template_hostescalation);
7257 
7258 		/* apply missing properties from template hostescalation... */
7259 		xodtemplate_get_inherited_string(&template_hostescalation->have_host_name, &template_hostescalation->host_name, &this_hostescalation->have_host_name, &this_hostescalation->host_name);
7260 		xodtemplate_get_inherited_string(&template_hostescalation->have_hostgroup_name, &template_hostescalation->hostgroup_name, &this_hostescalation->have_hostgroup_name, &this_hostescalation->hostgroup_name);
7261 		xodtemplate_get_inherited_string(&template_hostescalation->have_contact_groups, &template_hostescalation->contact_groups, &this_hostescalation->have_contact_groups, &this_hostescalation->contact_groups);
7262 		xodtemplate_get_inherited_string(&template_hostescalation->have_contacts, &template_hostescalation->contacts, &this_hostescalation->have_contacts, &this_hostescalation->contacts);
7263 
7264 		if(this_hostescalation->have_escalation_period == FALSE && template_hostescalation->have_escalation_period == TRUE) {
7265 			if(this_hostescalation->escalation_period == NULL && template_hostescalation->escalation_period != NULL)
7266 				this_hostescalation->escalation_period = (char *)strdup(template_hostescalation->escalation_period);
7267 			this_hostescalation->have_escalation_period = TRUE;
7268 			}
7269 		if(this_hostescalation->have_first_notification == FALSE && template_hostescalation->have_first_notification == TRUE) {
7270 			this_hostescalation->first_notification = template_hostescalation->first_notification;
7271 			this_hostescalation->have_first_notification = TRUE;
7272 			}
7273 		if(this_hostescalation->have_last_notification == FALSE && template_hostescalation->have_last_notification == TRUE) {
7274 			this_hostescalation->last_notification = template_hostescalation->last_notification;
7275 			this_hostescalation->have_last_notification = TRUE;
7276 			}
7277 		if(this_hostescalation->have_notification_interval == FALSE && template_hostescalation->have_notification_interval == TRUE) {
7278 			this_hostescalation->notification_interval = template_hostescalation->notification_interval;
7279 			this_hostescalation->have_notification_interval = TRUE;
7280 			}
7281 		if(this_hostescalation->have_escalation_options == FALSE && template_hostescalation->have_escalation_options == TRUE) {
7282 			this_hostescalation->escalate_on_down = template_hostescalation->escalate_on_down;
7283 			this_hostescalation->escalate_on_unreachable = template_hostescalation->escalate_on_unreachable;
7284 			this_hostescalation->escalate_on_recovery = template_hostescalation->escalate_on_recovery;
7285 			this_hostescalation->have_escalation_options = TRUE;
7286 			}
7287 		}
7288 
7289 	my_free(template_names);
7290 
7291 	return OK;
7292 	}
7293 
7294 
7295 
7296 /* resolves a hostextinfo object */
xodtemplate_resolve_hostextinfo(xodtemplate_hostextinfo * this_hostextinfo)7297 int xodtemplate_resolve_hostextinfo(xodtemplate_hostextinfo *this_hostextinfo) {
7298 	char *temp_ptr = NULL;
7299 	char *template_names = NULL;
7300 	char *template_name_ptr = NULL;
7301 	xodtemplate_hostextinfo *template_hostextinfo = NULL;
7302 
7303 	/* return if this object has already been resolved */
7304 	if(this_hostextinfo->has_been_resolved == TRUE)
7305 		return OK;
7306 
7307 	/* set the resolved flag */
7308 	this_hostextinfo->has_been_resolved = TRUE;
7309 
7310 	/* return if we have no template */
7311 	if(this_hostextinfo->template == NULL)
7312 		return OK;
7313 
7314 	if((template_names = (char *)strdup(this_hostextinfo->template)) == NULL)
7315 		return ERROR;
7316 
7317 	/* apply all templates */
7318 	template_name_ptr = template_names;
7319 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
7320 
7321 		template_hostextinfo = xodtemplate_find_hostextinfo(temp_ptr);
7322 		if(template_hostextinfo == NULL) {
7323 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in extended host info definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_hostextinfo->_config_file), this_hostextinfo->_start_line);
7324 			my_free(template_names);
7325 			return ERROR;
7326 			}
7327 
7328 		/* resolve the template hostextinfo... */
7329 		xodtemplate_resolve_hostextinfo(template_hostextinfo);
7330 
7331 		/* apply missing properties from template hostextinfo... */
7332 		if(this_hostextinfo->have_host_name == FALSE && template_hostextinfo->have_host_name == TRUE) {
7333 			if(this_hostextinfo->host_name == NULL && template_hostextinfo->host_name != NULL)
7334 				this_hostextinfo->host_name = (char *)strdup(template_hostextinfo->host_name);
7335 			this_hostextinfo->have_host_name = TRUE;
7336 			}
7337 		if(this_hostextinfo->have_hostgroup_name == FALSE && template_hostextinfo->have_hostgroup_name == TRUE) {
7338 			if(this_hostextinfo->hostgroup_name == NULL && template_hostextinfo->hostgroup_name != NULL)
7339 				this_hostextinfo->hostgroup_name = (char *)strdup(template_hostextinfo->hostgroup_name);
7340 			this_hostextinfo->have_hostgroup_name = TRUE;
7341 			}
7342 		if(this_hostextinfo->have_notes == FALSE && template_hostextinfo->have_notes == TRUE) {
7343 			if(this_hostextinfo->notes == NULL && template_hostextinfo->notes != NULL)
7344 				this_hostextinfo->notes = (char *)strdup(template_hostextinfo->notes);
7345 			this_hostextinfo->have_notes = TRUE;
7346 			}
7347 		if(this_hostextinfo->have_notes_url == FALSE && template_hostextinfo->have_notes_url == TRUE) {
7348 			if(this_hostextinfo->notes_url == NULL && template_hostextinfo->notes_url != NULL)
7349 				this_hostextinfo->notes_url = (char *)strdup(template_hostextinfo->notes_url);
7350 			this_hostextinfo->have_notes_url = TRUE;
7351 			}
7352 		if(this_hostextinfo->have_action_url == FALSE && template_hostextinfo->have_action_url == TRUE) {
7353 			if(this_hostextinfo->action_url == NULL && template_hostextinfo->action_url != NULL)
7354 				this_hostextinfo->action_url = (char *)strdup(template_hostextinfo->action_url);
7355 			this_hostextinfo->have_action_url = TRUE;
7356 			}
7357 		if(this_hostextinfo->have_icon_image == FALSE && template_hostextinfo->have_icon_image == TRUE) {
7358 			if(this_hostextinfo->icon_image == NULL && template_hostextinfo->icon_image != NULL)
7359 				this_hostextinfo->icon_image = (char *)strdup(template_hostextinfo->icon_image);
7360 			this_hostextinfo->have_icon_image = TRUE;
7361 			}
7362 		if(this_hostextinfo->have_icon_image_alt == FALSE && template_hostextinfo->have_icon_image_alt == TRUE) {
7363 			if(this_hostextinfo->icon_image_alt == NULL && template_hostextinfo->icon_image_alt != NULL)
7364 				this_hostextinfo->icon_image_alt = (char *)strdup(template_hostextinfo->icon_image_alt);
7365 			this_hostextinfo->have_icon_image_alt = TRUE;
7366 			}
7367 		if(this_hostextinfo->have_vrml_image == FALSE && template_hostextinfo->have_vrml_image == TRUE) {
7368 			if(this_hostextinfo->vrml_image == NULL && template_hostextinfo->vrml_image != NULL)
7369 				this_hostextinfo->vrml_image = (char *)strdup(template_hostextinfo->vrml_image);
7370 			this_hostextinfo->have_vrml_image = TRUE;
7371 			}
7372 		if(this_hostextinfo->have_statusmap_image == FALSE && template_hostextinfo->have_statusmap_image == TRUE) {
7373 			if(this_hostextinfo->statusmap_image == NULL && template_hostextinfo->statusmap_image != NULL)
7374 				this_hostextinfo->statusmap_image = (char *)strdup(template_hostextinfo->statusmap_image);
7375 			this_hostextinfo->have_statusmap_image = TRUE;
7376 			}
7377 		if(this_hostextinfo->have_2d_coords == FALSE && template_hostextinfo->have_2d_coords == TRUE) {
7378 			this_hostextinfo->x_2d = template_hostextinfo->x_2d;
7379 			this_hostextinfo->y_2d = template_hostextinfo->y_2d;
7380 			this_hostextinfo->have_2d_coords = TRUE;
7381 			}
7382 		if(this_hostextinfo->have_3d_coords == FALSE && template_hostextinfo->have_3d_coords == TRUE) {
7383 			this_hostextinfo->x_3d = template_hostextinfo->x_3d;
7384 			this_hostextinfo->y_3d = template_hostextinfo->y_3d;
7385 			this_hostextinfo->z_3d = template_hostextinfo->z_3d;
7386 			this_hostextinfo->have_3d_coords = TRUE;
7387 			}
7388 		}
7389 
7390 	my_free(template_names);
7391 
7392 	return OK;
7393 	}
7394 
7395 
7396 
7397 /* resolves a serviceextinfo object */
xodtemplate_resolve_serviceextinfo(xodtemplate_serviceextinfo * this_serviceextinfo)7398 int xodtemplate_resolve_serviceextinfo(xodtemplate_serviceextinfo *this_serviceextinfo) {
7399 	char *temp_ptr = NULL;
7400 	char *template_names = NULL;
7401 	char *template_name_ptr = NULL;
7402 	xodtemplate_serviceextinfo *template_serviceextinfo = NULL;
7403 
7404 	/* return if this object has already been resolved */
7405 	if(this_serviceextinfo->has_been_resolved == TRUE)
7406 		return OK;
7407 
7408 	/* set the resolved flag */
7409 	this_serviceextinfo->has_been_resolved = TRUE;
7410 
7411 	/* return if we have no template */
7412 	if(this_serviceextinfo->template == NULL)
7413 		return OK;
7414 
7415 	if((template_names = (char *)strdup(this_serviceextinfo->template)) == NULL)
7416 		return ERROR;
7417 
7418 	/* apply all templates */
7419 	template_name_ptr = template_names;
7420 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
7421 
7422 		template_serviceextinfo = xodtemplate_find_serviceextinfo(temp_ptr);
7423 		if(template_serviceextinfo == NULL) {
7424 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Template '%s' specified in extended service info definition could not be not found (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_serviceextinfo->_config_file), this_serviceextinfo->_start_line);
7425 			my_free(template_names);
7426 			return ERROR;
7427 			}
7428 
7429 		/* resolve the template serviceextinfo... */
7430 		xodtemplate_resolve_serviceextinfo(template_serviceextinfo);
7431 
7432 		/* apply missing properties from template serviceextinfo... */
7433 		if(this_serviceextinfo->have_host_name == FALSE && template_serviceextinfo->have_host_name == TRUE) {
7434 			if(this_serviceextinfo->host_name == NULL && template_serviceextinfo->host_name != NULL)
7435 				this_serviceextinfo->host_name = (char *)strdup(template_serviceextinfo->host_name);
7436 			this_serviceextinfo->have_host_name = TRUE;
7437 			}
7438 		if(this_serviceextinfo->have_hostgroup_name == FALSE && template_serviceextinfo->have_hostgroup_name == TRUE) {
7439 			if(this_serviceextinfo->hostgroup_name == NULL && template_serviceextinfo->hostgroup_name != NULL)
7440 				this_serviceextinfo->hostgroup_name = (char *)strdup(template_serviceextinfo->hostgroup_name);
7441 			this_serviceextinfo->have_hostgroup_name = TRUE;
7442 			}
7443 		if(this_serviceextinfo->have_service_description == FALSE && template_serviceextinfo->have_service_description == TRUE) {
7444 			if(this_serviceextinfo->service_description == NULL && template_serviceextinfo->service_description != NULL)
7445 				this_serviceextinfo->service_description = (char *)strdup(template_serviceextinfo->service_description);
7446 			this_serviceextinfo->have_service_description = TRUE;
7447 			}
7448 		if(this_serviceextinfo->have_notes == FALSE && template_serviceextinfo->have_notes == TRUE) {
7449 			if(this_serviceextinfo->notes == NULL && template_serviceextinfo->notes != NULL)
7450 				this_serviceextinfo->notes = (char *)strdup(template_serviceextinfo->notes);
7451 			this_serviceextinfo->have_notes = TRUE;
7452 			}
7453 		if(this_serviceextinfo->have_notes_url == FALSE && template_serviceextinfo->have_notes_url == TRUE) {
7454 			if(this_serviceextinfo->notes_url == NULL && template_serviceextinfo->notes_url != NULL)
7455 				this_serviceextinfo->notes_url = (char *)strdup(template_serviceextinfo->notes_url);
7456 			this_serviceextinfo->have_notes_url = TRUE;
7457 			}
7458 		if(this_serviceextinfo->have_action_url == FALSE && template_serviceextinfo->have_action_url == TRUE) {
7459 			if(this_serviceextinfo->action_url == NULL && template_serviceextinfo->action_url != NULL)
7460 				this_serviceextinfo->action_url = (char *)strdup(template_serviceextinfo->action_url);
7461 			this_serviceextinfo->have_action_url = TRUE;
7462 			}
7463 		if(this_serviceextinfo->have_icon_image == FALSE && template_serviceextinfo->have_icon_image == TRUE) {
7464 			if(this_serviceextinfo->icon_image == NULL && template_serviceextinfo->icon_image != NULL)
7465 				this_serviceextinfo->icon_image = (char *)strdup(template_serviceextinfo->icon_image);
7466 			this_serviceextinfo->have_icon_image = TRUE;
7467 			}
7468 		if(this_serviceextinfo->have_icon_image_alt == FALSE && template_serviceextinfo->have_icon_image_alt == TRUE) {
7469 			if(this_serviceextinfo->icon_image_alt == NULL && template_serviceextinfo->icon_image_alt != NULL)
7470 				this_serviceextinfo->icon_image_alt = (char *)strdup(template_serviceextinfo->icon_image_alt);
7471 			this_serviceextinfo->have_icon_image_alt = TRUE;
7472 			}
7473 		}
7474 
7475 	my_free(template_names);
7476 
7477 	return OK;
7478 	}
7479 
7480 #endif
7481 
7482 
7483 
7484 /******************************************************************/
7485 /*************** OBJECT RECOMBOBULATION FUNCTIONS *****************/
7486 /******************************************************************/
7487 
7488 #ifdef NSCORE
7489 
7490 
7491 /* recombobulates contactgroup definitions */
xodtemplate_recombobulate_contactgroups(void)7492 int xodtemplate_recombobulate_contactgroups(void) {
7493 	xodtemplate_contact *temp_contact = NULL;
7494 	xodtemplate_contactgroup *temp_contactgroup = NULL;
7495 	xodtemplate_memberlist *temp_memberlist = NULL;
7496 	xodtemplate_memberlist *this_memberlist = NULL;
7497 	char *contactgroup_names = NULL;
7498 	char *temp_ptr = NULL;
7499 	char *new_members = NULL;
7500 
7501 	/* This should happen before we expand contactgroup members, to avoid duplicate contact memberships 01/07/2006 EG */
7502 	/* process all contacts that have contactgroup directives */
7503 	for(temp_contact = xodtemplate_contact_list; temp_contact != NULL; temp_contact = temp_contact->next) {
7504 
7505 		/* skip contacts without contactgroup directives or contact names */
7506 		if(temp_contact->contact_groups == NULL || temp_contact->contact_name == NULL)
7507 			continue;
7508 
7509 		/* preprocess the contactgroup list, to change "grp1,grp2,grp3,!grp2" into "grp1,grp3" */
7510 		if((contactgroup_names = xodtemplate_process_contactgroup_names(temp_contact->contact_groups, temp_contact->_config_file, temp_contact->_start_line)) == NULL)
7511 			return ERROR;
7512 
7513 		/* process the list of contactgroups */
7514 		for(temp_ptr = strtok(contactgroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) {
7515 
7516 			/* strip trailing spaces */
7517 			strip(temp_ptr);
7518 
7519 			/* find the contactgroup */
7520 			temp_contactgroup = xodtemplate_find_real_contactgroup(temp_ptr);
7521 			if(temp_contactgroup == NULL) {
7522 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find contactgroup '%s' specified in contact '%s' definition (config file '%s', starting on line %d)\n", temp_ptr, temp_contact->contact_name, xodtemplate_config_file_name(temp_contact->_config_file), temp_contact->_start_line);
7523 				my_free(contactgroup_names);
7524 				return ERROR;
7525 				}
7526 
7527 			/* add this contact to the contactgroup members directive */
7528 			if(temp_contactgroup->members == NULL)
7529 				temp_contactgroup->members = (char *)strdup(temp_contact->contact_name);
7530 			else {
7531 				new_members = (char *)realloc(temp_contactgroup->members, strlen(temp_contactgroup->members) + strlen(temp_contact->contact_name) + 2);
7532 				if(new_members != NULL) {
7533 					temp_contactgroup->members = new_members;
7534 					strcat(temp_contactgroup->members, ",");
7535 					strcat(temp_contactgroup->members, temp_contact->contact_name);
7536 					}
7537 				}
7538 			}
7539 
7540 		/* free memory */
7541 		my_free(contactgroup_names);
7542 		}
7543 
7544 
7545 	/* expand subgroup membership recursively */
7546 	for(temp_contactgroup = xodtemplate_contactgroup_list; temp_contactgroup; temp_contactgroup = temp_contactgroup->next)
7547 		xodtemplate_recombobulate_contactgroup_subgroups(temp_contactgroup, NULL);
7548 
7549 
7550 	/* expand members of all contactgroups - this could be done in xodtemplate_register_contactgroup(), but we can save the CGIs some work if we do it here */
7551 	for(temp_contactgroup = xodtemplate_contactgroup_list; temp_contactgroup; temp_contactgroup = temp_contactgroup->next) {
7552 
7553 		if(temp_contactgroup->members == NULL)
7554 			continue;
7555 
7556 		/* get list of contacts in the contactgroup */
7557 		temp_memberlist = xodtemplate_expand_contactgroups_and_contacts(temp_contactgroup->contactgroup_members, temp_contactgroup->members, temp_contactgroup->_config_file, temp_contactgroup->_start_line);
7558 
7559 		/* add all members to the contact group */
7560 		if(temp_memberlist == NULL) {
7561 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand member contacts specified in contactgroup (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_contactgroup->_config_file), temp_contactgroup->_start_line);
7562 			return ERROR;
7563 			}
7564 		my_free(temp_contactgroup->members);
7565 		for(this_memberlist = temp_memberlist; this_memberlist; this_memberlist = this_memberlist->next) {
7566 
7567 			/* add this contact to the contactgroup members directive */
7568 			if(temp_contactgroup->members == NULL)
7569 				temp_contactgroup->members = (char *)strdup(this_memberlist->name1);
7570 			else {
7571 				new_members = (char *)realloc(temp_contactgroup->members, strlen(temp_contactgroup->members) + strlen(this_memberlist->name1) + 2);
7572 				if(new_members != NULL) {
7573 					temp_contactgroup->members = new_members;
7574 					strcat(temp_contactgroup->members, ",");
7575 					strcat(temp_contactgroup->members, this_memberlist->name1);
7576 					}
7577 				}
7578 			}
7579 		xodtemplate_free_memberlist(&temp_memberlist);
7580 		}
7581 
7582 	return OK;
7583 	}
7584 
7585 
7586 
xodtemplate_recombobulate_contactgroup_subgroups(xodtemplate_contactgroup * temp_contactgroup,char ** members)7587 int xodtemplate_recombobulate_contactgroup_subgroups(xodtemplate_contactgroup *temp_contactgroup, char **members) {
7588 	xodtemplate_contactgroup *sub_group = NULL;
7589 	char *orig_cgmembers = NULL;
7590 	char *cgmembers = NULL;
7591 	char *newmembers = NULL;
7592 	char *buf = NULL;
7593 	char *ptr = NULL;
7594 
7595 	if(temp_contactgroup == NULL)
7596 		return ERROR;
7597 
7598 	/* resolve subgroup memberships first */
7599 	if(temp_contactgroup->contactgroup_members != NULL) {
7600 
7601 		/* save members, null pointer so we don't recurse into infinite hell */
7602 		orig_cgmembers = temp_contactgroup->contactgroup_members;
7603 		temp_contactgroup->contactgroup_members = NULL;
7604 
7605 		/* make new working copy of members */
7606 		cgmembers = (char *)strdup(orig_cgmembers);
7607 
7608 		ptr = cgmembers;
7609 		while((buf = ptr) != NULL) {
7610 
7611 			/* get next member for next run*/
7612 			ptr = strchr(ptr, ',');
7613 			if(ptr) {
7614 				ptr[0] = '\x0';
7615 				ptr++;
7616 				}
7617 
7618 			strip(buf);
7619 
7620 			/* find subgroup and recurse */
7621 			if((sub_group = xodtemplate_find_real_contactgroup(buf)) == NULL) {
7622 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find member group '%s' specified in contactgroup (config file '%s', starting on line %d)\n", buf, xodtemplate_config_file_name(temp_contactgroup->_config_file), temp_contactgroup->_start_line);
7623 				return ERROR;
7624 				}
7625 			xodtemplate_recombobulate_contactgroup_subgroups(sub_group, &newmembers);
7626 
7627 			/* add new (sub) members */
7628 			if(newmembers != NULL) {
7629 				if(temp_contactgroup->members == NULL)
7630 					temp_contactgroup->members = (char *)strdup(newmembers);
7631 				else if((temp_contactgroup->members = realloc(temp_contactgroup->members, strlen(temp_contactgroup->members) + strlen(newmembers) + 2))) {
7632 					strcat(temp_contactgroup->members, ",");
7633 					strcat(temp_contactgroup->members, newmembers);
7634 					}
7635 				}
7636 			}
7637 
7638 		/* free memory */
7639 		my_free(cgmembers);
7640 
7641 		/* restore group members */
7642 		temp_contactgroup->contactgroup_members = orig_cgmembers;
7643 		}
7644 
7645 	/* return contact members */
7646 	if(members != NULL)
7647 		*members = temp_contactgroup->members;
7648 
7649 	return OK;
7650 	}
7651 
7652 
7653 
7654 /* NOTE: this was originally implemented in the late alpha cycle of
7655  * 3.0 development, but was removed in 3.0b2, as flattening
7656  * contactgroups into a list of contacts makes it impossible for
7657  * NDOUtils to create a reverse mapping */
7658 /* recombobulates contacts in various object definitions */
xodtemplate_recombobulate_object_contacts(void)7659 int xodtemplate_recombobulate_object_contacts(void) {
7660 	return OK;
7661 	}
7662 
7663 
7664 /* recombobulates hostgroup definitions */
xodtemplate_recombobulate_hostgroups(void)7665 int xodtemplate_recombobulate_hostgroups(void) {
7666 	xodtemplate_host *temp_host = NULL;
7667 	xodtemplate_hostgroup *temp_hostgroup = NULL;
7668 	xodtemplate_memberlist *temp_memberlist = NULL;
7669 	xodtemplate_memberlist *this_memberlist = NULL;
7670 	char *hostgroup_names = NULL;
7671 	char *temp_ptr = NULL;
7672 	char *new_members = NULL;
7673 
7674 #ifdef DEBUG
7675 	printf("** PRE-EXPANSION 1\n");
7676 	for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup; temp_hostgroup = temp_hostgroup->next) {
7677 		printf("HOSTGROUP [%s]\n", temp_hostgroup->hostgroup_name);
7678 		printf("H MEMBERS: %s\n", temp_hostgroup->members);
7679 		printf("G MEMBERS: %s\n", temp_hostgroup->hostgroup_members);
7680 		printf("\n");
7681 		}
7682 #endif
7683 
7684 	/* This should happen before we expand hostgroup members, to avoid duplicate host memberships 01/07/2006 EG */
7685 	/* process all hosts that have hostgroup directives */
7686 	for(temp_host = xodtemplate_host_list; temp_host != NULL; temp_host = temp_host->next) {
7687 
7688 		/* skip hosts without hostgroup directives or host names */
7689 		if(temp_host->host_groups == NULL || temp_host->host_name == NULL)
7690 			continue;
7691 
7692 		/* skip hosts that shouldn't be registered */
7693 		if(temp_host->register_object == FALSE)
7694 			continue;
7695 
7696 		/* preprocess the hostgroup list, to change "grp1,grp2,grp3,!grp2" into "grp1,grp3" */
7697 		/* 10/18/07 EG an empty return value means an error occured */
7698 		if((hostgroup_names = xodtemplate_process_hostgroup_names(temp_host->host_groups, temp_host->_config_file, temp_host->_start_line)) == NULL)
7699 			return ERROR;
7700 
7701 		/* process the list of hostgroups */
7702 		for(temp_ptr = strtok(hostgroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) {
7703 
7704 			/* strip trailing spaces */
7705 			strip(temp_ptr);
7706 
7707 			/* find the hostgroup */
7708 			temp_hostgroup = xodtemplate_find_real_hostgroup(temp_ptr);
7709 			if(temp_hostgroup == NULL) {
7710 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find hostgroup '%s' specified in host '%s' definition (config file '%s', starting on line %d)\n", temp_ptr, temp_host->host_name, xodtemplate_config_file_name(temp_host->_config_file), temp_host->_start_line);
7711 				my_free(hostgroup_names);
7712 				return ERROR;
7713 				}
7714 
7715 			/* add this list to the hostgroup members directive */
7716 			if(temp_hostgroup->members == NULL)
7717 				temp_hostgroup->members = (char *)strdup(temp_host->host_name);
7718 			else {
7719 				new_members = (char *)realloc(temp_hostgroup->members, strlen(temp_hostgroup->members) + strlen(temp_host->host_name) + 2);
7720 				if(new_members != NULL) {
7721 					temp_hostgroup->members = new_members;
7722 					strcat(temp_hostgroup->members, ",");
7723 					strcat(temp_hostgroup->members, temp_host->host_name);
7724 					}
7725 				}
7726 			}
7727 
7728 		/* free memory */
7729 		my_free(hostgroup_names);
7730 		}
7731 
7732 #ifdef DEBUG
7733 	printf("** POST-EXPANSION 1\n");
7734 	for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup; temp_hostgroup = temp_hostgroup->next) {
7735 		printf("HOSTGROUP [%s]\n", temp_hostgroup->hostgroup_name);
7736 		printf("H MEMBERS: %s\n", temp_hostgroup->members);
7737 		printf("G MEMBERS: %s\n", temp_hostgroup->hostgroup_members);
7738 		printf("\n");
7739 		}
7740 #endif
7741 
7742 	/* expand subgroup membership recursively */
7743 	for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup; temp_hostgroup = temp_hostgroup->next)
7744 		xodtemplate_recombobulate_hostgroup_subgroups(temp_hostgroup, NULL);
7745 
7746 	/* expand members of all hostgroups - this could be done in xodtemplate_register_hostgroup(), but we can save the CGIs some work if we do it here */
7747 	for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup; temp_hostgroup = temp_hostgroup->next) {
7748 
7749 		if(temp_hostgroup->members == NULL && temp_hostgroup->hostgroup_members == NULL)
7750 			continue;
7751 
7752 		/* skip hostgroups that shouldn't be registered */
7753 		if(temp_hostgroup->register_object == FALSE)
7754 			continue;
7755 
7756 		/* get list of hosts in the hostgroup */
7757 		temp_memberlist = xodtemplate_expand_hostgroups_and_hosts(NULL, temp_hostgroup->members, temp_hostgroup->_config_file, temp_hostgroup->_start_line);
7758 
7759 		/* add all members to the host group */
7760 		if(temp_memberlist == NULL) {
7761 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand members specified in hostgroup (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_hostgroup->_config_file), temp_hostgroup->_start_line);
7762 			return ERROR;
7763 			}
7764 		my_free(temp_hostgroup->members);
7765 		for(this_memberlist = temp_memberlist; this_memberlist; this_memberlist = this_memberlist->next) {
7766 
7767 			/* add this host to the hostgroup members directive */
7768 			if(temp_hostgroup->members == NULL)
7769 				temp_hostgroup->members = (char *)strdup(this_memberlist->name1);
7770 			else {
7771 				new_members = (char *)realloc(temp_hostgroup->members, strlen(temp_hostgroup->members) + strlen(this_memberlist->name1) + 2);
7772 				if(new_members != NULL) {
7773 					temp_hostgroup->members = new_members;
7774 					strcat(temp_hostgroup->members, ",");
7775 					strcat(temp_hostgroup->members, this_memberlist->name1);
7776 					}
7777 				}
7778 			}
7779 		xodtemplate_free_memberlist(&temp_memberlist);
7780 		}
7781 
7782 #ifdef DEBUG
7783 	printf("** POST-EXPANSION 2\n");
7784 	for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup; temp_hostgroup = temp_hostgroup->next) {
7785 		printf("HOSTGROUP [%s]\n", temp_hostgroup->hostgroup_name);
7786 		printf("H MEMBERS: %s\n", temp_hostgroup->members);
7787 		printf("G MEMBERS: %s\n", temp_hostgroup->hostgroup_members);
7788 		printf("\n");
7789 		}
7790 #endif
7791 
7792 	return OK;
7793 	}
7794 
7795 
7796 
7797 
xodtemplate_recombobulate_hostgroup_subgroups(xodtemplate_hostgroup * temp_hostgroup,char ** members)7798 int xodtemplate_recombobulate_hostgroup_subgroups(xodtemplate_hostgroup *temp_hostgroup, char **members) {
7799 	xodtemplate_hostgroup *sub_group = NULL;
7800 	char *orig_hgmembers = NULL;
7801 	char *hgmembers = NULL;
7802 	char *newmembers = NULL;
7803 	char *buf = NULL;
7804 	char *ptr = NULL;
7805 
7806 	if(temp_hostgroup == NULL)
7807 		return ERROR;
7808 
7809 	/* resolve subgroup memberships first */
7810 	if(temp_hostgroup->hostgroup_members != NULL) {
7811 
7812 		/* save members, null pointer so we don't recurse into infinite hell */
7813 		orig_hgmembers = temp_hostgroup->hostgroup_members;
7814 		temp_hostgroup->hostgroup_members = NULL;
7815 
7816 		/* make new working copy of members */
7817 		hgmembers = (char *)strdup(orig_hgmembers);
7818 
7819 		ptr = hgmembers;
7820 		while((buf = ptr) != NULL) {
7821 
7822 			/* get next member for next run*/
7823 			ptr = strchr(ptr, ',');
7824 			if(ptr) {
7825 				ptr[0] = '\x0';
7826 				ptr++;
7827 				}
7828 
7829 			strip(buf);
7830 
7831 			/* find subgroup and recurse */
7832 			if((sub_group = xodtemplate_find_real_hostgroup(buf)) == NULL) {
7833 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find member group '%s' specified in hostgroup (config file '%s', starting on line %d)\n", buf, xodtemplate_config_file_name(temp_hostgroup->_config_file), temp_hostgroup->_start_line);
7834 				return ERROR;
7835 				}
7836 			xodtemplate_recombobulate_hostgroup_subgroups(sub_group, &newmembers);
7837 
7838 			/* add new (sub) members */
7839 			if(newmembers != NULL) {
7840 				if(temp_hostgroup->members == NULL)
7841 					temp_hostgroup->members = (char *)strdup(newmembers);
7842 				else if((temp_hostgroup->members = realloc(temp_hostgroup->members, strlen(temp_hostgroup->members) + strlen(newmembers) + 2))) {
7843 					strcat(temp_hostgroup->members, ",");
7844 					strcat(temp_hostgroup->members, newmembers);
7845 					}
7846 				}
7847 			}
7848 
7849 		/* free memory */
7850 		my_free(hgmembers);
7851 
7852 		/* restore group members */
7853 		temp_hostgroup->hostgroup_members = orig_hgmembers;
7854 		}
7855 
7856 	/* return host members */
7857 	if(members != NULL)
7858 		*members = temp_hostgroup->members;
7859 
7860 	return OK;
7861 	}
7862 
7863 
7864 
7865 /* recombobulates servicegroup definitions */
7866 /***** THIS NEEDS TO BE CALLED AFTER OBJECTS (SERVICES) ARE RESOLVED AND DUPLICATED *****/
xodtemplate_recombobulate_servicegroups(void)7867 int xodtemplate_recombobulate_servicegroups(void) {
7868 	xodtemplate_service *temp_service = NULL;
7869 	xodtemplate_servicegroup *temp_servicegroup = NULL;
7870 	xodtemplate_memberlist *temp_memberlist = NULL;
7871 	xodtemplate_memberlist *this_memberlist = NULL;
7872 	char *servicegroup_names = NULL;
7873 	char *member_names = NULL;
7874 	char *host_name = NULL;
7875 	char *service_description = NULL;
7876 	char *temp_ptr = NULL;
7877 	char *temp_ptr2 = NULL;
7878 	char *new_members = NULL;
7879 
7880 	/* This should happen before we expand servicegroup members, to avoid duplicate service memberships 01/07/2006 EG */
7881 	/* process all services that have servicegroup directives */
7882 	for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) {
7883 
7884 		/* skip services without servicegroup directives or service names */
7885 		if(temp_service->service_groups == NULL || temp_service->host_name == NULL || temp_service->service_description == NULL)
7886 			continue;
7887 
7888 		/* skip services that shouldn't be registered */
7889 		if(temp_service->register_object == FALSE)
7890 			continue;
7891 
7892 		/* preprocess the servicegroup list, to change "grp1,grp2,grp3,!grp2" into "grp1,grp3" */
7893 		/* 10/19/07 EG an empry return value means an error occured */
7894 		if((servicegroup_names = xodtemplate_process_servicegroup_names(temp_service->service_groups, temp_service->_config_file, temp_service->_start_line)) == NULL)
7895 			return ERROR;
7896 
7897 		/* process the list of servicegroups */
7898 		for(temp_ptr = strtok(servicegroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) {
7899 
7900 			/* strip trailing spaces */
7901 			strip(temp_ptr);
7902 
7903 			/* find the servicegroup */
7904 			temp_servicegroup = xodtemplate_find_real_servicegroup(temp_ptr);
7905 			if(temp_servicegroup == NULL) {
7906 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find servicegroup '%s' specified in service '%s' on host '%s' definition (config file '%s', starting on line %d)\n", temp_ptr, temp_service->service_description, temp_service->host_name, xodtemplate_config_file_name(temp_service->_config_file), temp_service->_start_line);
7907 				my_free(servicegroup_names);
7908 				return ERROR;
7909 				}
7910 
7911 			/* add this list to the servicegroup members directive */
7912 			if(temp_servicegroup->members == NULL) {
7913 				temp_servicegroup->members = (char *)malloc(strlen(temp_service->host_name) + strlen(temp_service->service_description) + 2);
7914 				if(temp_servicegroup->members != NULL) {
7915 					strcpy(temp_servicegroup->members, temp_service->host_name);
7916 					strcat(temp_servicegroup->members, ",");
7917 					strcat(temp_servicegroup->members, temp_service->service_description);
7918 					}
7919 				}
7920 			else {
7921 				new_members = (char *)realloc(temp_servicegroup->members, strlen(temp_servicegroup->members) + strlen(temp_service->host_name) + strlen(temp_service->service_description) + 3);
7922 				if(new_members != NULL) {
7923 					temp_servicegroup->members = new_members;
7924 					strcat(temp_servicegroup->members, ",");
7925 					strcat(temp_servicegroup->members, temp_service->host_name);
7926 					strcat(temp_servicegroup->members, ",");
7927 					strcat(temp_servicegroup->members, temp_service->service_description);
7928 					}
7929 				}
7930 			}
7931 
7932 		/* free servicegroup names */
7933 		my_free(servicegroup_names);
7934 		}
7935 
7936 
7937 	/* expand subgroup membership recursively */
7938 	for(temp_servicegroup = xodtemplate_servicegroup_list; temp_servicegroup; temp_servicegroup = temp_servicegroup->next)
7939 		xodtemplate_recombobulate_servicegroup_subgroups(temp_servicegroup, NULL);
7940 
7941 	/* expand members of all servicegroups - this could be done in xodtemplate_register_servicegroup(), but we can save the CGIs some work if we do it here */
7942 	for(temp_servicegroup = xodtemplate_servicegroup_list; temp_servicegroup; temp_servicegroup = temp_servicegroup->next) {
7943 
7944 		if(temp_servicegroup->members == NULL)
7945 			continue;
7946 
7947 		/* skip servicegroups that shouldn't be registered */
7948 		if(temp_servicegroup->register_object == FALSE)
7949 			continue;
7950 
7951 		member_names = temp_servicegroup->members;
7952 		temp_servicegroup->members = NULL;
7953 
7954 		for(temp_ptr = member_names; temp_ptr; temp_ptr = strchr(temp_ptr + 1, ',')) {
7955 
7956 			/* this is the host name */
7957 			if(host_name == NULL)
7958 				host_name = (char *)strdup((temp_ptr[0] == ',') ? temp_ptr + 1 : temp_ptr);
7959 
7960 			/* this is the service description */
7961 			else {
7962 				service_description = (char *)strdup(temp_ptr + 1);
7963 
7964 				/* strsep and strtok cannot be used, as they're used in expand_servicegroups...() */
7965 				temp_ptr2 = strchr(host_name, ',');
7966 				if(temp_ptr2)
7967 					temp_ptr2[0] = '\x0';
7968 				temp_ptr2 = strchr(service_description, ',');
7969 				if(temp_ptr2)
7970 					temp_ptr2[0] = '\x0';
7971 
7972 				/* strip trailing spaces */
7973 				strip(host_name);
7974 				strip(service_description);
7975 
7976 				/* get list of services in the servicegroup */
7977 				temp_memberlist = xodtemplate_expand_servicegroups_and_services(NULL, host_name, service_description, temp_servicegroup->_config_file, temp_servicegroup->_start_line);
7978 
7979 				/* add all members to the service group */
7980 				if(temp_memberlist == NULL) {
7981 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand member services specified in servicegroup (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_servicegroup->_config_file), temp_servicegroup->_start_line);
7982 					my_free(member_names);
7983 					my_free(host_name);
7984 					my_free(service_description);
7985 					return ERROR;
7986 					}
7987 
7988 				for(this_memberlist = temp_memberlist; this_memberlist; this_memberlist = this_memberlist->next) {
7989 
7990 					/* add this service to the servicegroup members directive */
7991 					if(temp_servicegroup->members == NULL) {
7992 						temp_servicegroup->members = (char *)malloc(strlen(this_memberlist->name1) + strlen(this_memberlist->name2) + 2);
7993 						if(temp_servicegroup != NULL) {
7994 							strcpy(temp_servicegroup->members, this_memberlist->name1);
7995 							strcat(temp_servicegroup->members, ",");
7996 							strcat(temp_servicegroup->members, this_memberlist->name2);
7997 							}
7998 						}
7999 					else {
8000 						new_members = (char *)realloc(temp_servicegroup->members, strlen(temp_servicegroup->members) + strlen(this_memberlist->name1) + strlen(this_memberlist->name2) + 3);
8001 						if(new_members != NULL) {
8002 							temp_servicegroup->members = new_members;
8003 							strcat(temp_servicegroup->members, ",");
8004 							strcat(temp_servicegroup->members, this_memberlist->name1);
8005 							strcat(temp_servicegroup->members, ",");
8006 							strcat(temp_servicegroup->members, this_memberlist->name2);
8007 							}
8008 						}
8009 					}
8010 				xodtemplate_free_memberlist(&temp_memberlist);
8011 
8012 				my_free(host_name);
8013 				my_free(service_description);
8014 				}
8015 			}
8016 
8017 		my_free(member_names);
8018 
8019 		/* error if there were an odd number of items specified (unmatched host/service pair) */
8020 		if(host_name != NULL) {
8021 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Servicegroup members must be specified in <host_name>,<service_description> pairs (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_servicegroup->_config_file), temp_servicegroup->_start_line);
8022 			my_free(host_name);
8023 			return ERROR;
8024 			}
8025 		}
8026 
8027 	return OK;
8028 	}
8029 
8030 
8031 
8032 
xodtemplate_recombobulate_servicegroup_subgroups(xodtemplate_servicegroup * temp_servicegroup,char ** members)8033 int xodtemplate_recombobulate_servicegroup_subgroups(xodtemplate_servicegroup *temp_servicegroup, char **members) {
8034 	xodtemplate_servicegroup *sub_group = NULL;
8035 	char *orig_sgmembers = NULL;
8036 	char *sgmembers = NULL;
8037 	char *newmembers = NULL;
8038 	char *buf = NULL;
8039 	char *ptr = NULL;
8040 
8041 	if(temp_servicegroup == NULL)
8042 		return ERROR;
8043 
8044 	/* resolve subgroup memberships first */
8045 	if(temp_servicegroup->servicegroup_members != NULL) {
8046 
8047 		/* save members, null pointer so we don't recurse into infinite hell */
8048 		orig_sgmembers = temp_servicegroup->servicegroup_members;
8049 		temp_servicegroup->servicegroup_members = NULL;
8050 
8051 		/* make new working copy of members */
8052 		sgmembers = (char *)strdup(orig_sgmembers);
8053 
8054 		ptr = sgmembers;
8055 		while((buf = ptr) != NULL) {
8056 
8057 			/* get next member for next run*/
8058 			ptr = strchr(ptr, ',');
8059 			if(ptr) {
8060 				ptr[0] = '\x0';
8061 				ptr++;
8062 				}
8063 
8064 			strip(buf);
8065 
8066 			/* find subgroup and recurse */
8067 			if((sub_group = xodtemplate_find_real_servicegroup(buf)) == NULL) {
8068 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find member group '%s' specified in servicegroup (config file '%s', starting on line %d)\n", buf, xodtemplate_config_file_name(temp_servicegroup->_config_file), temp_servicegroup->_start_line);
8069 				return ERROR;
8070 				}
8071 			xodtemplate_recombobulate_servicegroup_subgroups(sub_group, &newmembers);
8072 
8073 			/* add new (sub) members */
8074 			if(newmembers != NULL) {
8075 				if(temp_servicegroup->members == NULL)
8076 					temp_servicegroup->members = (char *)strdup(newmembers);
8077 				else if((temp_servicegroup->members = realloc(temp_servicegroup->members, strlen(temp_servicegroup->members) + strlen(newmembers) + 2))) {
8078 					strcat(temp_servicegroup->members, ",");
8079 					strcat(temp_servicegroup->members, newmembers);
8080 					}
8081 				}
8082 			}
8083 
8084 		/* free memory */
8085 		my_free(sgmembers);
8086 
8087 		/* restore group members */
8088 		temp_servicegroup->servicegroup_members = orig_sgmembers;
8089 		}
8090 
8091 	/* return service members */
8092 	if(members != NULL)
8093 		*members = temp_servicegroup->members;
8094 
8095 	return OK;
8096 	}
8097 
8098 #endif
8099 
8100 
8101 
8102 /******************************************************************/
8103 /******************* OBJECT SEARCH FUNCTIONS **********************/
8104 /******************************************************************/
8105 
8106 #ifdef NSCORE
8107 
8108 /* finds a specific timeperiod object */
xodtemplate_find_timeperiod(char * name)8109 xodtemplate_timeperiod *xodtemplate_find_timeperiod(char *name) {
8110 	xodtemplate_timeperiod temp_timeperiod;
8111 
8112 	if(name == NULL)
8113 		return NULL;
8114 
8115 	temp_timeperiod.name = name;
8116 
8117 	return skiplist_find_first(xobject_template_skiplists[X_TIMEPERIOD_SKIPLIST], &temp_timeperiod, NULL);
8118 	}
8119 
8120 
8121 /* finds a specific command object */
xodtemplate_find_command(char * name)8122 xodtemplate_command *xodtemplate_find_command(char *name) {
8123 	xodtemplate_command temp_command;
8124 
8125 	if(name == NULL)
8126 		return NULL;
8127 
8128 	temp_command.name = name;
8129 
8130 	return skiplist_find_first(xobject_template_skiplists[X_COMMAND_SKIPLIST], &temp_command, NULL);
8131 	}
8132 
8133 
8134 /* finds a specific contactgroup object */
xodtemplate_find_contactgroup(char * name)8135 xodtemplate_contactgroup *xodtemplate_find_contactgroup(char *name) {
8136 	xodtemplate_contactgroup temp_contactgroup;
8137 
8138 	if(name == NULL)
8139 		return NULL;
8140 
8141 	temp_contactgroup.name = name;
8142 
8143 	return skiplist_find_first(xobject_template_skiplists[X_CONTACTGROUP_SKIPLIST], &temp_contactgroup, NULL);
8144 	}
8145 
8146 
8147 /* finds a specific contactgroup object by its REAL name, not its TEMPLATE name */
xodtemplate_find_real_contactgroup(char * name)8148 xodtemplate_contactgroup *xodtemplate_find_real_contactgroup(char *name) {
8149 	xodtemplate_contactgroup temp_contactgroup;
8150 
8151 	if(name == NULL)
8152 		return NULL;
8153 
8154 	temp_contactgroup.contactgroup_name = name;
8155 
8156 	return skiplist_find_first(xobject_skiplists[X_CONTACTGROUP_SKIPLIST], &temp_contactgroup, NULL);
8157 	}
8158 
8159 
8160 /* finds a specific hostgroup object */
xodtemplate_find_hostgroup(char * name)8161 xodtemplate_hostgroup *xodtemplate_find_hostgroup(char *name) {
8162 	xodtemplate_hostgroup temp_hostgroup;
8163 
8164 	if(name == NULL)
8165 		return NULL;
8166 
8167 	temp_hostgroup.name = name;
8168 
8169 	return skiplist_find_first(xobject_template_skiplists[X_HOSTGROUP_SKIPLIST], &temp_hostgroup, NULL);
8170 	}
8171 
8172 
8173 /* finds a specific hostgroup object by its REAL name, not its TEMPLATE name */
xodtemplate_find_real_hostgroup(char * name)8174 xodtemplate_hostgroup *xodtemplate_find_real_hostgroup(char *name) {
8175 	xodtemplate_hostgroup temp_hostgroup;
8176 
8177 	if(name == NULL)
8178 		return NULL;
8179 
8180 	temp_hostgroup.hostgroup_name = name;
8181 
8182 	return skiplist_find_first(xobject_skiplists[X_HOSTGROUP_SKIPLIST], &temp_hostgroup, NULL);
8183 	}
8184 
8185 
8186 /* finds a specific servicegroup object */
xodtemplate_find_servicegroup(char * name)8187 xodtemplate_servicegroup *xodtemplate_find_servicegroup(char *name) {
8188 	xodtemplate_servicegroup temp_servicegroup;
8189 
8190 	if(name == NULL)
8191 		return NULL;
8192 
8193 	temp_servicegroup.name = name;
8194 
8195 	return skiplist_find_first(xobject_template_skiplists[X_SERVICEGROUP_SKIPLIST], &temp_servicegroup, NULL);
8196 	}
8197 
8198 
8199 /* finds a specific servicegroup object by its REAL name, not its TEMPLATE name */
xodtemplate_find_real_servicegroup(char * name)8200 xodtemplate_servicegroup *xodtemplate_find_real_servicegroup(char *name) {
8201 	xodtemplate_servicegroup temp_servicegroup;
8202 
8203 	if(name == NULL)
8204 		return NULL;
8205 
8206 	temp_servicegroup.servicegroup_name = name;
8207 
8208 	return skiplist_find_first(xobject_skiplists[X_SERVICEGROUP_SKIPLIST], &temp_servicegroup, NULL);
8209 	}
8210 
8211 
8212 /* finds a specific servicedependency object */
xodtemplate_find_servicedependency(char * name)8213 xodtemplate_servicedependency *xodtemplate_find_servicedependency(char *name) {
8214 	xodtemplate_servicedependency temp_servicedependency;
8215 
8216 	if(name == NULL)
8217 		return NULL;
8218 
8219 	temp_servicedependency.name = name;
8220 
8221 	return skiplist_find_first(xobject_template_skiplists[X_SERVICEDEPENDENCY_SKIPLIST], &temp_servicedependency, NULL);
8222 	}
8223 
8224 
8225 /* finds a specific serviceescalation object */
xodtemplate_find_serviceescalation(char * name)8226 xodtemplate_serviceescalation *xodtemplate_find_serviceescalation(char *name) {
8227 	xodtemplate_serviceescalation temp_serviceescalation;
8228 
8229 	if(name == NULL)
8230 		return NULL;
8231 
8232 	temp_serviceescalation.name = name;
8233 
8234 	return skiplist_find_first(xobject_template_skiplists[X_SERVICEESCALATION_SKIPLIST], &temp_serviceescalation, NULL);
8235 	}
8236 
8237 
8238 /* finds a specific contact object */
xodtemplate_find_contact(char * name)8239 xodtemplate_contact *xodtemplate_find_contact(char *name) {
8240 	xodtemplate_contact temp_contact;
8241 
8242 	if(name == NULL)
8243 		return NULL;
8244 
8245 	temp_contact.name = name;
8246 
8247 	return skiplist_find_first(xobject_template_skiplists[X_CONTACT_SKIPLIST], &temp_contact, NULL);
8248 	}
8249 
8250 
8251 /* finds a specific contact object by its REAL name, not its TEMPLATE name */
xodtemplate_find_real_contact(char * name)8252 xodtemplate_contact *xodtemplate_find_real_contact(char *name) {
8253 	xodtemplate_contact temp_contact;
8254 
8255 	if(name == NULL)
8256 		return NULL;
8257 
8258 	temp_contact.contact_name = name;
8259 
8260 	return skiplist_find_first(xobject_skiplists[X_CONTACT_SKIPLIST], &temp_contact, NULL);
8261 	}
8262 
8263 
8264 /* finds a specific host object */
xodtemplate_find_host(char * name)8265 xodtemplate_host *xodtemplate_find_host(char *name) {
8266 	xodtemplate_host temp_host;
8267 
8268 	if(name == NULL)
8269 		return NULL;
8270 
8271 	temp_host.name = name;
8272 
8273 	return skiplist_find_first(xobject_template_skiplists[X_HOST_SKIPLIST], &temp_host, NULL);
8274 	}
8275 
8276 
8277 /* finds a specific host object by its REAL name, not its TEMPLATE name */
xodtemplate_find_real_host(char * name)8278 xodtemplate_host *xodtemplate_find_real_host(char *name) {
8279 	xodtemplate_host temp_host;
8280 
8281 	if(name == NULL)
8282 		return NULL;
8283 
8284 	temp_host.host_name = name;
8285 
8286 	return skiplist_find_first(xobject_skiplists[X_HOST_SKIPLIST], &temp_host, NULL);
8287 	}
8288 
8289 
8290 /* finds a specific hostdependency object */
xodtemplate_find_hostdependency(char * name)8291 xodtemplate_hostdependency *xodtemplate_find_hostdependency(char *name) {
8292 	xodtemplate_hostdependency temp_hostdependency;
8293 
8294 	if(name == NULL)
8295 		return NULL;
8296 
8297 	temp_hostdependency.name = name;
8298 
8299 	return skiplist_find_first(xobject_template_skiplists[X_HOSTDEPENDENCY_SKIPLIST], &temp_hostdependency, NULL);
8300 	}
8301 
8302 
8303 /* finds a specific hostescalation object */
xodtemplate_find_hostescalation(char * name)8304 xodtemplate_hostescalation *xodtemplate_find_hostescalation(char *name) {
8305 	xodtemplate_hostescalation temp_hostescalation;
8306 
8307 	if(name == NULL)
8308 		return NULL;
8309 
8310 	temp_hostescalation.name = name;
8311 
8312 	return skiplist_find_first(xobject_template_skiplists[X_HOSTESCALATION_SKIPLIST], &temp_hostescalation, NULL);
8313 	}
8314 
8315 
8316 /* finds a specific hostextinfo object */
xodtemplate_find_hostextinfo(char * name)8317 xodtemplate_hostextinfo *xodtemplate_find_hostextinfo(char *name) {
8318 	xodtemplate_hostextinfo temp_hostextinfo;
8319 
8320 	if(name == NULL)
8321 		return NULL;
8322 
8323 	temp_hostextinfo.name = name;
8324 
8325 	return skiplist_find_first(xobject_template_skiplists[X_HOSTEXTINFO_SKIPLIST], &temp_hostextinfo, NULL);
8326 	}
8327 
8328 
8329 /* finds a specific serviceextinfo object */
xodtemplate_find_serviceextinfo(char * name)8330 xodtemplate_serviceextinfo *xodtemplate_find_serviceextinfo(char *name) {
8331 	xodtemplate_serviceextinfo temp_serviceextinfo;
8332 
8333 	if(name == NULL)
8334 		return NULL;
8335 
8336 	temp_serviceextinfo.name = name;
8337 
8338 	return skiplist_find_first(xobject_template_skiplists[X_SERVICEEXTINFO_SKIPLIST], &temp_serviceextinfo, NULL);
8339 	}
8340 
8341 
8342 /* finds a specific service object */
xodtemplate_find_service(char * name)8343 xodtemplate_service *xodtemplate_find_service(char *name) {
8344 	xodtemplate_service temp_service;
8345 
8346 	if(name == NULL)
8347 		return NULL;
8348 
8349 	temp_service.name = name;
8350 
8351 	return skiplist_find_first(xobject_template_skiplists[X_SERVICE_SKIPLIST], &temp_service, NULL);
8352 	}
8353 
8354 
8355 /* finds a specific service object by its REAL name, not its TEMPLATE name */
xodtemplate_find_real_service(char * host_name,char * service_description)8356 xodtemplate_service *xodtemplate_find_real_service(char *host_name, char *service_description) {
8357 	xodtemplate_service temp_service;
8358 
8359 	if(host_name == NULL || service_description == NULL)
8360 		return NULL;
8361 
8362 	temp_service.host_name = host_name;
8363 	temp_service.service_description = service_description;
8364 
8365 	return skiplist_find_first(xobject_skiplists[X_SERVICE_SKIPLIST], &temp_service, NULL);
8366 	}
8367 
8368 #endif
8369 
8370 
8371 
8372 /******************************************************************/
8373 /**************** OBJECT REGISTRATION FUNCTIONS *******************/
8374 /******************************************************************/
8375 
8376 /* registers object definitions */
xodtemplate_register_objects(void)8377 int xodtemplate_register_objects(void) {
8378 	int result = OK;
8379 	xodtemplate_timeperiod *temp_timeperiod = NULL;
8380 	xodtemplate_command *temp_command = NULL;
8381 	xodtemplate_contactgroup *temp_contactgroup = NULL;
8382 	xodtemplate_hostgroup *temp_hostgroup = NULL;
8383 	xodtemplate_servicegroup *temp_servicegroup = NULL;
8384 	xodtemplate_contact *temp_contact = NULL;
8385 	xodtemplate_host *temp_host = NULL;
8386 	xodtemplate_service *temp_service = NULL;
8387 	xodtemplate_servicedependency *temp_servicedependency = NULL;
8388 	xodtemplate_serviceescalation *temp_serviceescalation = NULL;
8389 	xodtemplate_hostdependency *temp_hostdependency = NULL;
8390 	xodtemplate_hostescalation *temp_hostescalation = NULL;
8391 	void *ptr = NULL;
8392 
8393 	/* register timeperiods */
8394 	/*for(temp_timeperiod=xodtemplate_timeperiod_list;temp_timeperiod!=NULL;temp_timeperiod=temp_timeperiod->next){*/
8395 	ptr = NULL;
8396 	for(temp_timeperiod = (xodtemplate_timeperiod *)skiplist_get_first(xobject_skiplists[X_TIMEPERIOD_SKIPLIST], &ptr); temp_timeperiod != NULL; temp_timeperiod = (xodtemplate_timeperiod *)skiplist_get_next(&ptr)) {
8397 		if((result = xodtemplate_register_timeperiod(temp_timeperiod)) == ERROR)
8398 			return ERROR;
8399 		}
8400 
8401 	/* register commands */
8402 	/*for(temp_command=xodtemplate_command_list;temp_command!=NULL;temp_command=temp_command->next){*/
8403 	ptr = NULL;
8404 	for(temp_command = (xodtemplate_command *)skiplist_get_first(xobject_skiplists[X_COMMAND_SKIPLIST], &ptr); temp_command != NULL; temp_command = (xodtemplate_command *)skiplist_get_next(&ptr)) {
8405 		if((result = xodtemplate_register_command(temp_command)) == ERROR)
8406 			return ERROR;
8407 		}
8408 
8409 	/* register contactgroups */
8410 	/*for(temp_contactgroup=xodtemplate_contactgroup_list;temp_contactgroup!=NULL;temp_contactgroup=temp_contactgroup->next){*/
8411 	ptr = NULL;
8412 	for(temp_contactgroup = (xodtemplate_contactgroup *)skiplist_get_first(xobject_skiplists[X_CONTACTGROUP_SKIPLIST], &ptr); temp_contactgroup != NULL; temp_contactgroup = (xodtemplate_contactgroup *)skiplist_get_next(&ptr)) {
8413 		if((result = xodtemplate_register_contactgroup(temp_contactgroup)) == ERROR)
8414 			return ERROR;
8415 		}
8416 
8417 	/* register hostgroups */
8418 	/*for(temp_hostgroup=xodtemplate_hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){*/
8419 	ptr = NULL;
8420 	for(temp_hostgroup = (xodtemplate_hostgroup *)skiplist_get_first(xobject_skiplists[X_HOSTGROUP_SKIPLIST], &ptr); temp_hostgroup != NULL; temp_hostgroup = (xodtemplate_hostgroup *)skiplist_get_next(&ptr)) {
8421 		if((result = xodtemplate_register_hostgroup(temp_hostgroup)) == ERROR)
8422 			return ERROR;
8423 		}
8424 
8425 	/* register servicegroups */
8426 	/*for(temp_servicegroup=xodtemplate_servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next){*/
8427 	ptr = NULL;
8428 	for(temp_servicegroup = (xodtemplate_servicegroup *)skiplist_get_first(xobject_skiplists[X_SERVICEGROUP_SKIPLIST], &ptr); temp_servicegroup != NULL; temp_servicegroup = (xodtemplate_servicegroup *)skiplist_get_next(&ptr)) {
8429 		if((result = xodtemplate_register_servicegroup(temp_servicegroup)) == ERROR)
8430 			return ERROR;
8431 		}
8432 
8433 	/* register contacts */
8434 	/*for(temp_contact=xodtemplate_contact_list;temp_contact!=NULL;temp_contact=temp_contact->next){*/
8435 	ptr = NULL;
8436 	for(temp_contact = (xodtemplate_contact *)skiplist_get_first(xobject_skiplists[X_CONTACT_SKIPLIST], &ptr); temp_contact != NULL; temp_contact = (xodtemplate_contact *)skiplist_get_next(&ptr)) {
8437 		if((result = xodtemplate_register_contact(temp_contact)) == ERROR)
8438 			return ERROR;
8439 		}
8440 
8441 	/* register hosts */
8442 	/*for(temp_host=xodtemplate_host_list;temp_host!=NULL;temp_host=temp_host->next){*/
8443 	ptr = NULL;
8444 	for(temp_host = (xodtemplate_host *)skiplist_get_first(xobject_skiplists[X_HOST_SKIPLIST], &ptr); temp_host != NULL; temp_host = (xodtemplate_host *)skiplist_get_next(&ptr)) {
8445 		if((result = xodtemplate_register_host(temp_host)) == ERROR)
8446 			return ERROR;
8447 		}
8448 
8449 	/* register services */
8450 	/*for(temp_service=xodtemplate_service_list;temp_service!=NULL;temp_service=temp_service->next){*/
8451 	ptr = NULL;
8452 	for(temp_service = (xodtemplate_service *)skiplist_get_first(xobject_skiplists[X_SERVICE_SKIPLIST], &ptr); temp_service != NULL; temp_service = (xodtemplate_service *)skiplist_get_next(&ptr)) {
8453 
8454 		if((result = xodtemplate_register_service(temp_service)) == ERROR)
8455 			return ERROR;
8456 		}
8457 
8458 	/* register service dependencies */
8459 	/*for(temp_servicedependency=xodtemplate_servicedependency_list;temp_servicedependency!=NULL;temp_servicedependency=temp_servicedependency->next){*/
8460 	ptr = NULL;
8461 	for(temp_servicedependency = (xodtemplate_servicedependency *)skiplist_get_first(xobject_skiplists[X_SERVICEDEPENDENCY_SKIPLIST], &ptr); temp_servicedependency != NULL; temp_servicedependency = (xodtemplate_servicedependency *)skiplist_get_next(&ptr)) {
8462 		if((result = xodtemplate_register_servicedependency(temp_servicedependency)) == ERROR)
8463 			return ERROR;
8464 		}
8465 
8466 	/* register service escalations */
8467 	/*for(temp_serviceescalation=xodtemplate_serviceescalation_list;temp_serviceescalation!=NULL;temp_serviceescalation=temp_serviceescalation->next){*/
8468 	ptr = NULL;
8469 	for(temp_serviceescalation = (xodtemplate_serviceescalation *)skiplist_get_first(xobject_skiplists[X_SERVICEESCALATION_SKIPLIST], &ptr); temp_serviceescalation != NULL; temp_serviceescalation = (xodtemplate_serviceescalation *)skiplist_get_next(&ptr)) {
8470 		if((result = xodtemplate_register_serviceescalation(temp_serviceescalation)) == ERROR)
8471 			return ERROR;
8472 		}
8473 
8474 	/* register host dependencies */
8475 	/*for(temp_hostdependency=xodtemplate_hostdependency_list;temp_hostdependency!=NULL;temp_hostdependency=temp_hostdependency->next){*/
8476 	ptr = NULL;
8477 	for(temp_hostdependency = (xodtemplate_hostdependency *)skiplist_get_first(xobject_skiplists[X_HOSTDEPENDENCY_SKIPLIST], &ptr); temp_hostdependency != NULL; temp_hostdependency = (xodtemplate_hostdependency *)skiplist_get_next(&ptr)) {
8478 		if((result = xodtemplate_register_hostdependency(temp_hostdependency)) == ERROR)
8479 			return ERROR;
8480 		}
8481 
8482 	/* register host escalations */
8483 	/*for(temp_hostescalation=xodtemplate_hostescalation_list;temp_hostescalation!=NULL;temp_hostescalation=temp_hostescalation->next){*/
8484 	ptr = NULL;
8485 	for(temp_hostescalation = (xodtemplate_hostescalation *)skiplist_get_first(xobject_skiplists[X_HOSTESCALATION_SKIPLIST], &ptr); temp_hostescalation != NULL; temp_hostescalation = (xodtemplate_hostescalation *)skiplist_get_next(&ptr)) {
8486 		if((result = xodtemplate_register_hostescalation(temp_hostescalation)) == ERROR)
8487 			return ERROR;
8488 		}
8489 
8490 	return OK;
8491 	}
8492 
8493 
8494 
8495 /* registers a timeperiod definition */
xodtemplate_register_timeperiod(xodtemplate_timeperiod * this_timeperiod)8496 int xodtemplate_register_timeperiod(xodtemplate_timeperiod *this_timeperiod) {
8497 	xodtemplate_daterange *temp_daterange = NULL;
8498 	timeperiod *new_timeperiod = NULL;
8499 	daterange *new_daterange = NULL;
8500 	timerange *new_timerange = NULL;
8501 	timeperiodexclusion *new_timeperiodexclusion = NULL;
8502 	int day = 0;
8503 	int range = 0;
8504 	int x = 0;
8505 	char *day_range_ptr = NULL;
8506 	char *day_range_start_buffer = NULL;
8507 	char *temp_ptr = NULL;
8508 	unsigned long range_start_time = 0L;
8509 	unsigned long range_end_time = 0L;
8510 
8511 
8512 	/* bail out if we shouldn't register this object */
8513 	if(this_timeperiod->register_object == FALSE)
8514 		return OK;
8515 
8516 	/* add the timeperiod */
8517 	new_timeperiod = add_timeperiod(this_timeperiod->timeperiod_name, this_timeperiod->alias);
8518 
8519 	/* return with an error if we couldn't add the timeperiod */
8520 	if(new_timeperiod == NULL) {
8521 		logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register timeperiod (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_timeperiod->_config_file), this_timeperiod->_start_line);
8522 		return ERROR;
8523 		}
8524 
8525 	/* add all exceptions to timeperiod */
8526 	for(x = 0; x < DATERANGE_TYPES; x++) {
8527 		for(temp_daterange = this_timeperiod->exceptions[x]; temp_daterange != NULL; temp_daterange = temp_daterange->next) {
8528 
8529 			/* skip null entries */
8530 			if(temp_daterange->timeranges == NULL || !strcmp(temp_daterange->timeranges, XODTEMPLATE_NULL))
8531 				continue;
8532 
8533 			/* add new exception to timeperiod */
8534 			new_daterange = add_exception_to_timeperiod(new_timeperiod, temp_daterange->type, temp_daterange->syear, temp_daterange->smon, temp_daterange->smday, temp_daterange->swday, temp_daterange->swday_offset, temp_daterange->eyear, temp_daterange->emon, temp_daterange->emday, temp_daterange->ewday, temp_daterange->ewday_offset, temp_daterange->skip_interval);
8535 			if(new_daterange == NULL) {
8536 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add date exception to timeperiod (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_timeperiod->_config_file), this_timeperiod->_start_line);
8537 				return ERROR;
8538 				}
8539 
8540 			/* add timeranges to exception */
8541 			day_range_ptr = temp_daterange->timeranges;
8542 			range = 0;
8543 			for(day_range_start_buffer = my_strsep(&day_range_ptr, ", "); day_range_start_buffer != NULL; day_range_start_buffer = my_strsep(&day_range_ptr, ", ")) {
8544 
8545 				range++;
8546 
8547 				/* get time ranges */
8548 				if(xodtemplate_get_time_ranges(day_range_start_buffer, &range_start_time, &range_end_time) == ERROR) {
8549 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not parse timerange #%d of timeperiod (config file '%s', starting on line %d)\n", range, xodtemplate_config_file_name(this_timeperiod->_config_file), this_timeperiod->_start_line);
8550 					return ERROR;
8551 					}
8552 
8553 				/* add the new time range to the date range */
8554 				new_timerange = add_timerange_to_daterange(new_daterange, range_start_time, range_end_time);
8555 				if(new_timerange == NULL) {
8556 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add timerange #%d to timeperiod (config file '%s', starting on line %d)\n", range, xodtemplate_config_file_name(this_timeperiod->_config_file), this_timeperiod->_start_line);
8557 					return ERROR;
8558 					}
8559 				}
8560 			}
8561 		}
8562 
8563 	/* add all necessary timeranges to timeperiod */
8564 	for(day = 0; day < 7; day++) {
8565 
8566 		/* skip null entries */
8567 		if(this_timeperiod->timeranges[day] == NULL || !strcmp(this_timeperiod->timeranges[day], XODTEMPLATE_NULL))
8568 			continue;
8569 
8570 		day_range_ptr = this_timeperiod->timeranges[day];
8571 		range = 0;
8572 		for(day_range_start_buffer = my_strsep(&day_range_ptr, ", "); day_range_start_buffer != NULL; day_range_start_buffer = my_strsep(&day_range_ptr, ", ")) {
8573 
8574 			range++;
8575 
8576 			/* get time ranges */
8577 			if(xodtemplate_get_time_ranges(day_range_start_buffer, &range_start_time, &range_end_time) == ERROR) {
8578 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not parse timerange #%d for day %d of timeperiod (config file '%s', starting on line %d)\n", range, day, xodtemplate_config_file_name(this_timeperiod->_config_file), this_timeperiod->_start_line);
8579 				return ERROR;
8580 				}
8581 
8582 			/* add the new time range to the time period */
8583 			new_timerange = add_timerange_to_timeperiod(new_timeperiod, day, range_start_time, range_end_time);
8584 			if(new_timerange == NULL) {
8585 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add timerange #%d for day %d to timeperiod (config file '%s', starting on line %d)\n", range, day, xodtemplate_config_file_name(this_timeperiod->_config_file), this_timeperiod->_start_line);
8586 				return ERROR;
8587 				}
8588 			}
8589 
8590 		}
8591 
8592 	/* add timeperiod exclusions */
8593 	if(this_timeperiod->exclusions) {
8594 		for(temp_ptr = strtok(this_timeperiod->exclusions, ","); temp_ptr != NULL; temp_ptr = strtok(NULL, ",")) {
8595 			strip(temp_ptr);
8596 			new_timeperiodexclusion = add_exclusion_to_timeperiod(new_timeperiod, temp_ptr);
8597 			if(new_timeperiodexclusion == NULL) {
8598 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add excluded timeperiod '%s' to timeperiod (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(this_timeperiod->_config_file), this_timeperiod->_start_line);
8599 				return ERROR;
8600 				}
8601 			}
8602 		}
8603 
8604 	return OK;
8605 	}
8606 
8607 
8608 
8609 /* parses timerange string into start and end minutes */
xodtemplate_get_time_ranges(char * buf,unsigned long * range_start,unsigned long * range_end)8610 int xodtemplate_get_time_ranges(char *buf, unsigned long *range_start, unsigned long *range_end) {
8611 	char *range_ptr = NULL;
8612 	char *range_buffer = NULL;
8613 	char *time_ptr = NULL;
8614 	char *time_buffer = NULL;
8615 	int hours = 0;
8616 	int minutes = 0;
8617 
8618 	if(buf == NULL || range_start == NULL || range_end == NULL)
8619 		return ERROR;
8620 
8621 	range_ptr = buf;
8622 	range_buffer = my_strsep(&range_ptr, "-");
8623 	if(range_buffer == NULL)
8624 		return ERROR;
8625 
8626 	time_ptr = range_buffer;
8627 	time_buffer = my_strsep(&time_ptr, ":");
8628 	if(time_buffer == NULL)
8629 		return ERROR;
8630 	hours = atoi(time_buffer);
8631 
8632 	time_buffer = my_strsep(&time_ptr, ":");
8633 	if(time_buffer == NULL)
8634 		return ERROR;
8635 	minutes = atoi(time_buffer);
8636 
8637 	/* calculate the range start time in seconds */
8638 	*range_start = (unsigned long)((minutes * 60) + (hours * 60 * 60));
8639 
8640 	range_buffer = my_strsep(&range_ptr, "-");
8641 	if(range_buffer == NULL)
8642 		return ERROR;
8643 
8644 	time_ptr = range_buffer;
8645 	time_buffer = my_strsep(&time_ptr, ":");
8646 	if(time_buffer == NULL)
8647 		return ERROR;
8648 	hours = atoi(time_buffer);
8649 
8650 	time_buffer = my_strsep(&time_ptr, ":");
8651 	if(time_buffer == NULL)
8652 		return ERROR;
8653 	minutes = atoi(time_buffer);
8654 
8655 	/* calculate the range end time in seconds */
8656 	*range_end = (unsigned long)((minutes * 60) + (hours * 3600));
8657 
8658 	return OK;
8659 	}
8660 
8661 
8662 
8663 /* registers a command definition */
xodtemplate_register_command(xodtemplate_command * this_command)8664 int xodtemplate_register_command(xodtemplate_command *this_command) {
8665 	command *new_command = NULL;
8666 
8667 	/* bail out if we shouldn't register this object */
8668 	if(this_command->register_object == FALSE)
8669 		return OK;
8670 
8671 	/* add the command */
8672 	new_command = add_command(this_command->command_name, this_command->command_line);
8673 
8674 	/* return with an error if we couldn't add the command */
8675 	if(new_command == NULL) {
8676 		logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register command (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_command->_config_file), this_command->_start_line);
8677 		return ERROR;
8678 		}
8679 
8680 	return OK;
8681 	}
8682 
8683 
8684 
8685 /* registers a contactgroup definition */
xodtemplate_register_contactgroup(xodtemplate_contactgroup * this_contactgroup)8686 int xodtemplate_register_contactgroup(xodtemplate_contactgroup *this_contactgroup) {
8687 	contactgroup *new_contactgroup = NULL;
8688 	contactsmember *new_contactsmember = NULL;
8689 	char *contact_name = NULL;
8690 
8691 	/* bail out if we shouldn't register this object */
8692 	if(this_contactgroup->register_object == FALSE)
8693 		return OK;
8694 
8695 	/* add the contact group */
8696 	new_contactgroup = add_contactgroup(this_contactgroup->contactgroup_name, this_contactgroup->alias);
8697 
8698 	/* return with an error if we couldn't add the contactgroup */
8699 	if(new_contactgroup == NULL) {
8700 		logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register contactgroup (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_contactgroup->_config_file), this_contactgroup->_start_line);
8701 		return ERROR;
8702 		}
8703 
8704 	/* Need to check for NULL because strtok could use a NULL value to check the previous string's token value */
8705 	if(this_contactgroup->members != NULL) {
8706 		for(contact_name = strtok(this_contactgroup->members, ","); contact_name != NULL; contact_name = strtok(NULL, ",")) {
8707 			strip(contact_name);
8708 			new_contactsmember = add_contact_to_contactgroup(new_contactgroup, contact_name);
8709 			if(new_contactsmember == NULL) {
8710 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contact '%s' to contactgroup (config file '%s', starting on line %d)\n", contact_name, xodtemplate_config_file_name(this_contactgroup->_config_file), this_contactgroup->_start_line);
8711 				return ERROR;
8712 				}
8713 			}
8714 		}
8715 
8716 	return OK;
8717 	}
8718 
8719 
8720 
8721 /* registers a hostgroup definition */
xodtemplate_register_hostgroup(xodtemplate_hostgroup * this_hostgroup)8722 int xodtemplate_register_hostgroup(xodtemplate_hostgroup *this_hostgroup) {
8723 	hostgroup *new_hostgroup = NULL;
8724 	hostsmember *new_hostsmember = NULL;
8725 	char *host_name = NULL;
8726 
8727 	/* bail out if we shouldn't register this object */
8728 	if(this_hostgroup->register_object == FALSE)
8729 		return OK;
8730 
8731 	/* add the  host group */
8732 	new_hostgroup = add_hostgroup(this_hostgroup->hostgroup_name, this_hostgroup->alias, this_hostgroup->notes, this_hostgroup->notes_url, this_hostgroup->action_url);
8733 
8734 	/* return with an error if we couldn't add the hostgroup */
8735 	if(new_hostgroup == NULL) {
8736 		logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register hostgroup (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_hostgroup->_config_file), this_hostgroup->_start_line);
8737 		return ERROR;
8738 		}
8739 
8740 	if(this_hostgroup->members != NULL) {
8741 		for(host_name = strtok(this_hostgroup->members, ","); host_name != NULL; host_name = strtok(NULL, ",")) {
8742 			strip(host_name);
8743 			new_hostsmember = add_host_to_hostgroup(new_hostgroup, host_name);
8744 			if(new_hostsmember == NULL) {
8745 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add host '%s' to hostgroup (config file '%s', starting on line %d)\n", host_name, xodtemplate_config_file_name(this_hostgroup->_config_file), this_hostgroup->_start_line);
8746 				return ERROR;
8747 				}
8748 			}
8749 		}
8750 
8751 	return OK;
8752 	}
8753 
8754 
8755 
8756 /* registers a servicegroup definition */
xodtemplate_register_servicegroup(xodtemplate_servicegroup * this_servicegroup)8757 int xodtemplate_register_servicegroup(xodtemplate_servicegroup *this_servicegroup) {
8758 	servicegroup *new_servicegroup = NULL;
8759 	servicesmember *new_servicesmember = NULL;
8760 	char *host_name = NULL;
8761 	char *svc_description = NULL;
8762 
8763 	/* bail out if we shouldn't register this object */
8764 	if(this_servicegroup->register_object == FALSE)
8765 		return OK;
8766 
8767 	/* add the  service group */
8768 	new_servicegroup = add_servicegroup(this_servicegroup->servicegroup_name, this_servicegroup->alias, this_servicegroup->notes, this_servicegroup->notes_url, this_servicegroup->action_url);
8769 
8770 	/* return with an error if we couldn't add the servicegroup */
8771 	if(new_servicegroup == NULL) {
8772 		logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register servicegroup (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_servicegroup->_config_file), this_servicegroup->_start_line);
8773 		return ERROR;
8774 		}
8775 
8776 	if(this_servicegroup->members != NULL) {
8777 		for(host_name = strtok(this_servicegroup->members, ","); host_name != NULL; host_name = strtok(NULL, ",")) {
8778 			strip(host_name);
8779 			svc_description = strtok(NULL, ",");
8780 			if(svc_description == NULL) {
8781 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Missing service name in servicegroup definition (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_servicegroup->_config_file), this_servicegroup->_start_line);
8782 				return ERROR;
8783 				}
8784 			strip(svc_description);
8785 
8786 			new_servicesmember = add_service_to_servicegroup(new_servicegroup, host_name, svc_description);
8787 			if(new_servicesmember == NULL) {
8788 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add service '%s' on host '%s' to servicegroup (config file '%s', starting on line %d)\n", svc_description, host_name, xodtemplate_config_file_name(this_servicegroup->_config_file), this_servicegroup->_start_line);
8789 				return ERROR;
8790 				}
8791 			}
8792 		}
8793 
8794 	return OK;
8795 	}
8796 
8797 
8798 
8799 /* registers a servicedependency definition */
xodtemplate_register_servicedependency(xodtemplate_servicedependency * this_servicedependency)8800 int xodtemplate_register_servicedependency(xodtemplate_servicedependency *this_servicedependency) {
8801 	servicedependency *new_servicedependency = NULL;
8802 
8803 	/* bail out if we shouldn't register this object */
8804 	if(this_servicedependency->register_object == FALSE)
8805 		return OK;
8806 
8807 	/* throw a warning on servicedeps that have no options */
8808 	if(this_servicedependency->have_notification_dependency_options == FALSE && this_servicedependency->have_execution_dependency_options == FALSE) {
8809 		logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Ignoring lame service dependency (config file '%s', line %d)\n", xodtemplate_config_file_name(this_servicedependency->_config_file), this_servicedependency->_start_line);
8810 		return OK;
8811 		}
8812 
8813 	/* add the servicedependency */
8814 	if(this_servicedependency->have_execution_dependency_options == TRUE) {
8815 
8816 		new_servicedependency = add_service_dependency(this_servicedependency->dependent_host_name, this_servicedependency->dependent_service_description, this_servicedependency->host_name, this_servicedependency->service_description, EXECUTION_DEPENDENCY, this_servicedependency->inherits_parent, this_servicedependency->fail_execute_on_ok, this_servicedependency->fail_execute_on_warning, this_servicedependency->fail_execute_on_unknown, this_servicedependency->fail_execute_on_critical, this_servicedependency->fail_execute_on_pending, this_servicedependency->dependency_period);
8817 
8818 		/* return with an error if we couldn't add the servicedependency */
8819 		if(new_servicedependency == NULL) {
8820 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register service execution dependency (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_servicedependency->_config_file), this_servicedependency->_start_line);
8821 			return ERROR;
8822 			}
8823 		}
8824 	if(this_servicedependency->have_notification_dependency_options == TRUE) {
8825 
8826 		new_servicedependency = add_service_dependency(this_servicedependency->dependent_host_name, this_servicedependency->dependent_service_description, this_servicedependency->host_name, this_servicedependency->service_description, NOTIFICATION_DEPENDENCY, this_servicedependency->inherits_parent, this_servicedependency->fail_notify_on_ok, this_servicedependency->fail_notify_on_warning, this_servicedependency->fail_notify_on_unknown, this_servicedependency->fail_notify_on_critical, this_servicedependency->fail_notify_on_pending, this_servicedependency->dependency_period);
8827 
8828 		/* return with an error if we couldn't add the servicedependency */
8829 		if(new_servicedependency == NULL) {
8830 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register service notification dependency (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_servicedependency->_config_file), this_servicedependency->_start_line);
8831 			return ERROR;
8832 			}
8833 		}
8834 
8835 	return OK;
8836 	}
8837 
8838 
8839 
8840 /* registers a serviceescalation definition */
xodtemplate_register_serviceescalation(xodtemplate_serviceescalation * this_serviceescalation)8841 int xodtemplate_register_serviceescalation(xodtemplate_serviceescalation *this_serviceescalation) {
8842 	serviceescalation *new_serviceescalation = NULL;
8843 	contactsmember *new_contactsmember = NULL;
8844 	contactgroupsmember *new_contactgroupsmember = NULL;
8845 	char *contact_name = NULL;
8846 	char *contact_group = NULL;
8847 
8848 	/* bail out if we shouldn't register this object */
8849 	if(this_serviceescalation->register_object == FALSE)
8850 		return OK;
8851 
8852 	/* default options if none specified */
8853 	if(this_serviceescalation->have_escalation_options == FALSE) {
8854 		this_serviceescalation->escalate_on_warning = TRUE;
8855 		this_serviceescalation->escalate_on_unknown = TRUE;
8856 		this_serviceescalation->escalate_on_critical = TRUE;
8857 		this_serviceescalation->escalate_on_recovery = TRUE;
8858 		}
8859 
8860 	/* add the serviceescalation */
8861 	new_serviceescalation = add_serviceescalation(this_serviceescalation->host_name, this_serviceescalation->service_description, this_serviceescalation->first_notification, this_serviceescalation->last_notification, this_serviceescalation->notification_interval, this_serviceescalation->escalation_period, this_serviceescalation->escalate_on_warning, this_serviceescalation->escalate_on_unknown, this_serviceescalation->escalate_on_critical, this_serviceescalation->escalate_on_recovery);
8862 
8863 	/* return with an error if we couldn't add the serviceescalation */
8864 	if(new_serviceescalation == NULL) {
8865 		logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register service escalation (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_serviceescalation->_config_file), this_serviceescalation->_start_line);
8866 		return ERROR;
8867 		}
8868 
8869 	/* add the contact groups */
8870 	if(this_serviceescalation->contact_groups != NULL) {
8871 
8872 		for(contact_group = strtok(this_serviceescalation->contact_groups, ","); contact_group != NULL; contact_group = strtok(NULL, ", ")) {
8873 
8874 			strip(contact_group);
8875 			new_contactgroupsmember = add_contactgroup_to_serviceescalation(new_serviceescalation, contact_group);
8876 			if(new_contactgroupsmember == NULL) {
8877 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contactgroup '%s' to service escalation (config file '%s', starting on line %d)\n", contact_group, xodtemplate_config_file_name(this_serviceescalation->_config_file), this_serviceescalation->_start_line);
8878 				return ERROR;
8879 				}
8880 			}
8881 		}
8882 
8883 	/* add the contacts */
8884 	if(this_serviceescalation->contacts != NULL) {
8885 
8886 		for(contact_name = strtok(this_serviceescalation->contacts, ","); contact_name != NULL; contact_name = strtok(NULL, ", ")) {
8887 
8888 			strip(contact_name);
8889 			new_contactsmember = add_contact_to_serviceescalation(new_serviceescalation, contact_name);
8890 			if(new_contactsmember == NULL) {
8891 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contact '%s' to service escalation (config file '%s', starting on line %d)\n", contact_name, xodtemplate_config_file_name(this_serviceescalation->_config_file), this_serviceescalation->_start_line);
8892 				return ERROR;
8893 				}
8894 			}
8895 		}
8896 
8897 	return OK;
8898 	}
8899 
8900 
8901 
8902 /* registers a contact definition */
xodtemplate_register_contact(xodtemplate_contact * this_contact)8903 int xodtemplate_register_contact(xodtemplate_contact *this_contact) {
8904 	contact *new_contact = NULL;
8905 	char *command_name = NULL;
8906 	commandsmember *new_commandsmember = NULL;
8907 	xodtemplate_customvariablesmember *temp_customvariablesmember = NULL;
8908 
8909 	/* bail out if we shouldn't register this object */
8910 	if(this_contact->register_object == FALSE)
8911 		return OK;
8912 
8913 	/* add the contact */
8914 	new_contact = add_contact(this_contact->contact_name, this_contact->alias, this_contact->email, this_contact->pager, this_contact->address, this_contact->service_notification_period, this_contact->host_notification_period, this_contact->notify_on_service_recovery, this_contact->notify_on_service_critical, this_contact->notify_on_service_warning, this_contact->notify_on_service_unknown, this_contact->notify_on_service_flapping, this_contact->notify_on_service_downtime, this_contact->notify_on_host_recovery, this_contact->notify_on_host_down, this_contact->notify_on_host_unreachable, this_contact->notify_on_host_flapping, this_contact->notify_on_host_downtime, this_contact->host_notifications_enabled, this_contact->service_notifications_enabled, this_contact->can_submit_commands, this_contact->retain_status_information, this_contact->retain_nonstatus_information);
8915 
8916 	/* return with an error if we couldn't add the contact */
8917 	if(new_contact == NULL) {
8918 		logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register contact (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_contact->_config_file), this_contact->_start_line);
8919 		return ERROR;
8920 		}
8921 
8922 	/* add all the host notification commands */
8923 	if(this_contact->host_notification_commands != NULL) {
8924 
8925 		for(command_name = strtok(this_contact->host_notification_commands, ", "); command_name != NULL; command_name = strtok(NULL, ", ")) {
8926 			new_commandsmember = add_host_notification_command_to_contact(new_contact, command_name);
8927 			if(new_commandsmember == NULL) {
8928 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add host notification command '%s' to contact (config file '%s', starting on line %d)\n", command_name, xodtemplate_config_file_name(this_contact->_config_file), this_contact->_start_line);
8929 				return ERROR;
8930 				}
8931 			}
8932 		}
8933 
8934 	/* add all the service notification commands */
8935 	if(this_contact->service_notification_commands != NULL) {
8936 
8937 		for(command_name = strtok(this_contact->service_notification_commands, ", "); command_name != NULL; command_name = strtok(NULL, ", ")) {
8938 			new_commandsmember = add_service_notification_command_to_contact(new_contact, command_name);
8939 			if(new_commandsmember == NULL) {
8940 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add service notification command '%s' to contact (config file '%s', starting on line %d)\n", command_name, xodtemplate_config_file_name(this_contact->_config_file), this_contact->_start_line);
8941 				return ERROR;
8942 				}
8943 			}
8944 		}
8945 
8946 	/* add all custom variables */
8947 	for(temp_customvariablesmember = this_contact->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) {
8948 		if((add_custom_variable_to_contact(new_contact, temp_customvariablesmember->variable_name, temp_customvariablesmember->variable_value)) == NULL) {
8949 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not custom variable to contact (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_contact->_config_file), this_contact->_start_line);
8950 			return ERROR;
8951 			}
8952 		}
8953 
8954 	return OK;
8955 	}
8956 
8957 
8958 
8959 /* registers a host definition */
xodtemplate_register_host(xodtemplate_host * this_host)8960 int xodtemplate_register_host(xodtemplate_host *this_host) {
8961 	host *new_host = NULL;
8962 	char *parent_host = NULL;
8963 	hostsmember *new_hostsmember = NULL;
8964 	contactsmember *new_contactsmember = NULL;
8965 	contactgroupsmember *new_contactgroupsmember = NULL;
8966 	char *contact_name = NULL;
8967 	char *contact_group = NULL;
8968 	xodtemplate_customvariablesmember *temp_customvariablesmember = NULL;
8969 
8970 	/* bail out if we shouldn't register this object */
8971 	if(this_host->register_object == FALSE)
8972 		return OK;
8973 
8974 	/* if host has no alias or address, use host name - added 3/11/05 */
8975 	if(this_host->alias == NULL && this_host->host_name != NULL)
8976 		this_host->alias = (char *)strdup(this_host->host_name);
8977 	if(this_host->address == NULL && this_host->host_name != NULL)
8978 		this_host->address = (char *)strdup(this_host->host_name);
8979 
8980 	/* add the host definition */
8981 	new_host = add_host(this_host->host_name, this_host->display_name, this_host->alias, (this_host->address == NULL) ? this_host->host_name : this_host->address, this_host->check_period, this_host->initial_state, this_host->check_interval, this_host->retry_interval, this_host->max_check_attempts, this_host->notify_on_recovery, this_host->notify_on_down, this_host->notify_on_unreachable, this_host->notify_on_flapping, this_host->notify_on_downtime, this_host->notification_interval, this_host->first_notification_delay, this_host->notification_period, this_host->notifications_enabled, this_host->check_command, this_host->active_checks_enabled, this_host->passive_checks_enabled, this_host->event_handler, this_host->event_handler_enabled, this_host->flap_detection_enabled, this_host->low_flap_threshold, this_host->high_flap_threshold, this_host->flap_detection_on_up, this_host->flap_detection_on_down, this_host->flap_detection_on_unreachable, this_host->stalk_on_up, this_host->stalk_on_down, this_host->stalk_on_unreachable, this_host->process_perf_data, this_host->failure_prediction_enabled, this_host->failure_prediction_options, this_host->check_freshness, this_host->freshness_threshold, this_host->notes, this_host->notes_url, this_host->action_url, this_host->icon_image, this_host->icon_image_alt, this_host->vrml_image, this_host->statusmap_image, this_host->x_2d, this_host->y_2d, this_host->have_2d_coords, this_host->x_3d, this_host->y_3d, this_host->z_3d, this_host->have_3d_coords, TRUE, this_host->retain_status_information, this_host->retain_nonstatus_information, this_host->obsess_over_host);
8982 
8983 
8984 	/* return with an error if we couldn't add the host */
8985 	if(new_host == NULL) {
8986 		logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register host (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_host->_config_file), this_host->_start_line);
8987 		return ERROR;
8988 		}
8989 
8990 	/* add the parent hosts */
8991 	if(this_host->parents != NULL) {
8992 
8993 		for(parent_host = strtok(this_host->parents, ","); parent_host != NULL; parent_host = strtok(NULL, ",")) {
8994 			strip(parent_host);
8995 			new_hostsmember = add_parent_host_to_host(new_host, parent_host);
8996 			if(new_hostsmember == NULL) {
8997 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add parent host '%s' to host (config file '%s', starting on line %d)\n", parent_host, xodtemplate_config_file_name(this_host->_config_file), this_host->_start_line);
8998 				return ERROR;
8999 				}
9000 			}
9001 		}
9002 
9003 	/* add all contact groups to the host */
9004 	if(this_host->contact_groups != NULL) {
9005 
9006 		for(contact_group = strtok(this_host->contact_groups, ","); contact_group != NULL; contact_group = strtok(NULL, ",")) {
9007 
9008 			strip(contact_group);
9009 			new_contactgroupsmember = add_contactgroup_to_host(new_host, contact_group);
9010 			if(new_contactgroupsmember == NULL) {
9011 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contactgroup '%s' to host (config file '%s', starting on line %d)\n", contact_group, xodtemplate_config_file_name(this_host->_config_file), this_host->_start_line);
9012 				return ERROR;
9013 				}
9014 			}
9015 		}
9016 
9017 	/* add all contacts to the host */
9018 	if(this_host->contacts != NULL) {
9019 
9020 		for(contact_name = strtok(this_host->contacts, ","); contact_name != NULL; contact_name = strtok(NULL, ",")) {
9021 
9022 			strip(contact_name);
9023 			new_contactsmember = add_contact_to_host(new_host, contact_name);
9024 			if(new_contactsmember == NULL) {
9025 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contact '%s' to host (config file '%s', starting on line %d)\n", contact_name, xodtemplate_config_file_name(this_host->_config_file), this_host->_start_line);
9026 				return ERROR;
9027 				}
9028 			}
9029 		}
9030 
9031 	/* add all custom variables */
9032 	for(temp_customvariablesmember = this_host->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) {
9033 		if((add_custom_variable_to_host(new_host, temp_customvariablesmember->variable_name, temp_customvariablesmember->variable_value)) == NULL) {
9034 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not custom variable to host (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_host->_config_file), this_host->_start_line);
9035 			return ERROR;
9036 			}
9037 		}
9038 
9039 	return OK;
9040 	}
9041 
9042 
9043 
9044 /* registers a service definition */
xodtemplate_register_service(xodtemplate_service * this_service)9045 int xodtemplate_register_service(xodtemplate_service *this_service) {
9046 	service *new_service = NULL;
9047 	contactsmember *new_contactsmember = NULL;
9048 	contactgroupsmember *new_contactgroupsmember = NULL;
9049 	char *contact_name = NULL;
9050 	char *contact_group = NULL;
9051 	xodtemplate_customvariablesmember *temp_customvariablesmember = NULL;
9052 
9053 	/* bail out if we shouldn't register this object */
9054 	if(this_service->register_object == FALSE)
9055 		return OK;
9056 
9057 	/* add the service */
9058 	new_service = add_service(this_service->host_name, this_service->service_description, this_service->display_name, this_service->check_period, this_service->initial_state, this_service->max_check_attempts, this_service->parallelize_check, this_service->passive_checks_enabled, this_service->check_interval, this_service->retry_interval, this_service->notification_interval, this_service->first_notification_delay, this_service->notification_period, this_service->notify_on_recovery, this_service->notify_on_unknown, this_service->notify_on_warning, this_service->notify_on_critical, this_service->notify_on_flapping, this_service->notify_on_downtime, this_service->notifications_enabled, this_service->is_volatile, this_service->event_handler, this_service->event_handler_enabled, this_service->check_command, this_service->active_checks_enabled, this_service->flap_detection_enabled, this_service->low_flap_threshold, this_service->high_flap_threshold, this_service->flap_detection_on_ok, this_service->flap_detection_on_warning, this_service->flap_detection_on_unknown, this_service->flap_detection_on_critical, this_service->stalk_on_ok, this_service->stalk_on_warning, this_service->stalk_on_unknown, this_service->stalk_on_critical, this_service->process_perf_data, this_service->failure_prediction_enabled, this_service->failure_prediction_options, this_service->check_freshness, this_service->freshness_threshold, this_service->notes, this_service->notes_url, this_service->action_url, this_service->icon_image, this_service->icon_image_alt, this_service->retain_status_information, this_service->retain_nonstatus_information, this_service->obsess_over_service);
9059 
9060 	/* return with an error if we couldn't add the service */
9061 	if(new_service == NULL) {
9062 		logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register service (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_service->_config_file), this_service->_start_line);
9063 		return ERROR;
9064 		}
9065 
9066 	/* add all contact groups to the service */
9067 	if(this_service->contact_groups != NULL) {
9068 
9069 		for(contact_group = strtok(this_service->contact_groups, ","); contact_group != NULL; contact_group = strtok(NULL, ",")) {
9070 
9071 			strip(contact_group);
9072 			new_contactgroupsmember = add_contactgroup_to_service(new_service, contact_group);
9073 			if(new_contactgroupsmember == NULL) {
9074 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contactgroup '%s' to service (config file '%s', starting on line %d)\n", contact_group, xodtemplate_config_file_name(this_service->_config_file), this_service->_start_line);
9075 				return ERROR;
9076 				}
9077 			}
9078 		}
9079 
9080 	/* add all the contacts to the service */
9081 	if(this_service->contacts != NULL) {
9082 
9083 		for(contact_name = strtok(this_service->contacts, ","); contact_name != NULL; contact_name = strtok(NULL, ",")) {
9084 
9085 			/* add this contact to the service definition */
9086 			strip(contact_name);
9087 			new_contactsmember = add_contact_to_service(new_service, contact_name);
9088 
9089 			/* stop adding contacts if we ran into an error */
9090 			if(new_contactsmember == NULL) {
9091 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contact '%s' to service (config file '%s', starting on line %d)\n", contact_name, xodtemplate_config_file_name(this_service->_config_file), this_service->_start_line);
9092 				return ERROR;
9093 				}
9094 			}
9095 		}
9096 
9097 	/* add all custom variables */
9098 	for(temp_customvariablesmember = this_service->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) {
9099 		if((add_custom_variable_to_service(new_service, temp_customvariablesmember->variable_name, temp_customvariablesmember->variable_value)) == NULL) {
9100 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not custom variable to service (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_service->_config_file), this_service->_start_line);
9101 			return ERROR;
9102 			}
9103 		}
9104 
9105 	return OK;
9106 	}
9107 
9108 
9109 
9110 /* registers a hostdependency definition */
xodtemplate_register_hostdependency(xodtemplate_hostdependency * this_hostdependency)9111 int xodtemplate_register_hostdependency(xodtemplate_hostdependency *this_hostdependency) {
9112 	hostdependency *new_hostdependency = NULL;
9113 
9114 	/* bail out if we shouldn't register this object */
9115 	if(this_hostdependency->register_object == FALSE)
9116 		return OK;
9117 
9118 	/* add the host execution dependency */
9119 	if(this_hostdependency->have_execution_dependency_options == TRUE) {
9120 
9121 		new_hostdependency = add_host_dependency(this_hostdependency->dependent_host_name, this_hostdependency->host_name, EXECUTION_DEPENDENCY, this_hostdependency->inherits_parent, this_hostdependency->fail_execute_on_up, this_hostdependency->fail_execute_on_down, this_hostdependency->fail_execute_on_unreachable, this_hostdependency->fail_execute_on_pending, this_hostdependency->dependency_period);
9122 
9123 		/* return with an error if we couldn't add the hostdependency */
9124 		if(new_hostdependency == NULL) {
9125 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register host execution dependency (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_hostdependency->_config_file), this_hostdependency->_start_line);
9126 			return ERROR;
9127 			}
9128 		}
9129 
9130 	/* add the host notification dependency */
9131 	if(this_hostdependency->have_notification_dependency_options == TRUE) {
9132 
9133 		new_hostdependency = add_host_dependency(this_hostdependency->dependent_host_name, this_hostdependency->host_name, NOTIFICATION_DEPENDENCY, this_hostdependency->inherits_parent, this_hostdependency->fail_notify_on_up, this_hostdependency->fail_notify_on_down, this_hostdependency->fail_notify_on_unreachable, this_hostdependency->fail_notify_on_pending, this_hostdependency->dependency_period);
9134 
9135 		/* return with an error if we couldn't add the hostdependency */
9136 		if(new_hostdependency == NULL) {
9137 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register host notification dependency (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_hostdependency->_config_file), this_hostdependency->_start_line);
9138 			return ERROR;
9139 			}
9140 		}
9141 
9142 	return OK;
9143 	}
9144 
9145 
9146 
9147 /* registers a hostescalation definition */
xodtemplate_register_hostescalation(xodtemplate_hostescalation * this_hostescalation)9148 int xodtemplate_register_hostescalation(xodtemplate_hostescalation *this_hostescalation) {
9149 	hostescalation *new_hostescalation = NULL;
9150 	contactsmember *new_contactsmember = NULL;
9151 	contactgroupsmember *new_contactgroupsmember = NULL;
9152 	char *contact_name = NULL;
9153 	char *contact_group = NULL;
9154 
9155 	/* bail out if we shouldn't register this object */
9156 	if(this_hostescalation->register_object == FALSE)
9157 		return OK;
9158 
9159 	/* default options if none specified */
9160 	if(this_hostescalation->have_escalation_options == FALSE) {
9161 		this_hostescalation->escalate_on_down = TRUE;
9162 		this_hostescalation->escalate_on_unreachable = TRUE;
9163 		this_hostescalation->escalate_on_recovery = TRUE;
9164 		}
9165 
9166 	/* add the hostescalation */
9167 	new_hostescalation = add_hostescalation(this_hostescalation->host_name, this_hostescalation->first_notification, this_hostescalation->last_notification, this_hostescalation->notification_interval, this_hostescalation->escalation_period, this_hostescalation->escalate_on_down, this_hostescalation->escalate_on_unreachable, this_hostescalation->escalate_on_recovery);
9168 
9169 	/* return with an error if we couldn't add the hostescalation */
9170 	if(new_hostescalation == NULL) {
9171 		logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not register host escalation (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(this_hostescalation->_config_file), this_hostescalation->_start_line);
9172 		return ERROR;
9173 		}
9174 
9175 	/* add all contact groups */
9176 	if(this_hostescalation->contact_groups != NULL) {
9177 
9178 		for(contact_group = strtok(this_hostescalation->contact_groups, ","); contact_group != NULL; contact_group = strtok(NULL, ",")) {
9179 
9180 			strip(contact_group);
9181 			new_contactgroupsmember = add_contactgroup_to_hostescalation(new_hostescalation, contact_group);
9182 			if(new_contactgroupsmember == NULL) {
9183 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contactgroup '%s' to host escalation (config file '%s', starting on line %d)\n", contact_group, xodtemplate_config_file_name(this_hostescalation->_config_file), this_hostescalation->_start_line);
9184 				return ERROR;
9185 				}
9186 			}
9187 		}
9188 
9189 	/* add the contacts */
9190 	if(this_hostescalation->contacts != NULL) {
9191 
9192 		for(contact_name = strtok(this_hostescalation->contacts, ","); contact_name != NULL; contact_name = strtok(NULL, ", ")) {
9193 
9194 			strip(contact_name);
9195 			new_contactsmember = add_contact_to_hostescalation(new_hostescalation, contact_name);
9196 			if(new_contactsmember == NULL) {
9197 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contact '%s' to host escalation (config file '%s', starting on line %d)\n", contact_name, xodtemplate_config_file_name(this_hostescalation->_config_file), this_hostescalation->_start_line);
9198 				return ERROR;
9199 				}
9200 			}
9201 		}
9202 
9203 	return OK;
9204 	}
9205 
9206 
9207 
9208 
9209 /******************************************************************/
9210 /********************** SORTING FUNCTIONS *************************/
9211 /******************************************************************/
9212 
9213 #ifdef NSCORE
9214 
9215 /* sorts all objects by name */
xodtemplate_sort_objects(void)9216 int xodtemplate_sort_objects(void) {
9217 
9218 	/* NOTE: with skiplists, we no longer need to sort things manually... */
9219 	return OK;
9220 
9221 	/* sort timeperiods */
9222 	if(xodtemplate_sort_timeperiods() == ERROR)
9223 		return ERROR;
9224 
9225 	/* sort commands */
9226 	if(xodtemplate_sort_commands() == ERROR)
9227 		return ERROR;
9228 
9229 	/* sort contactgroups */
9230 	if(xodtemplate_sort_contactgroups() == ERROR)
9231 		return ERROR;
9232 
9233 	/* sort hostgroups */
9234 	if(xodtemplate_sort_hostgroups() == ERROR)
9235 		return ERROR;
9236 
9237 	/* sort servicegroups */
9238 	if(xodtemplate_sort_servicegroups() == ERROR)
9239 		return ERROR;
9240 
9241 	/* sort contacts */
9242 	if(xodtemplate_sort_contacts() == ERROR)
9243 		return ERROR;
9244 
9245 	/* sort hosts */
9246 	if(xodtemplate_sort_hosts() == ERROR)
9247 		return ERROR;
9248 
9249 	/* sort services */
9250 	if(xodtemplate_sort_services() == ERROR)
9251 		return ERROR;
9252 
9253 	/* sort service dependencies */
9254 	if(xodtemplate_sort_servicedependencies() == ERROR)
9255 		return ERROR;
9256 
9257 	/* sort service escalations */
9258 	if(xodtemplate_sort_serviceescalations() == ERROR)
9259 		return ERROR;
9260 
9261 	/* sort host dependencies */
9262 	if(xodtemplate_sort_hostdependencies() == ERROR)
9263 		return ERROR;
9264 
9265 	/* sort hostescalations */
9266 	if(xodtemplate_sort_hostescalations() == ERROR)
9267 		return ERROR;
9268 
9269 	/* sort host extended info */
9270 	/* NOT NEEDED */
9271 
9272 	/* sort service extended info */
9273 	/* NOT NEEDED */
9274 
9275 	return OK;
9276 	}
9277 
9278 
9279 /* used to compare two strings (object names) */
xodtemplate_compare_strings1(char * string1,char * string2)9280 int xodtemplate_compare_strings1(char *string1, char *string2) {
9281 
9282 	if(string1 == NULL && string2 == NULL)
9283 		return 0;
9284 	else if(string1 == NULL)
9285 		return -1;
9286 	else if(string2 == NULL)
9287 		return 1;
9288 	else
9289 		return strcmp(string1, string2);
9290 	}
9291 
9292 
9293 /* used to compare two sets of strings (dually-named objects, i.e. services) */
xodtemplate_compare_strings2(char * string1a,char * string1b,char * string2a,char * string2b)9294 int xodtemplate_compare_strings2(char *string1a, char *string1b, char *string2a, char *string2b) {
9295 	int result;
9296 
9297 	if((result = xodtemplate_compare_strings1(string1a, string2a)) == 0)
9298 		result = xodtemplate_compare_strings1(string1b, string2b);
9299 
9300 	return result;
9301 	}
9302 
9303 
9304 /* sort timeperiods by name */
xodtemplate_sort_timeperiods()9305 int xodtemplate_sort_timeperiods() {
9306 	xodtemplate_timeperiod *new_timeperiod_list = NULL;
9307 	xodtemplate_timeperiod *temp_timeperiod = NULL;
9308 	xodtemplate_timeperiod *last_timeperiod = NULL;
9309 	xodtemplate_timeperiod *temp_timeperiod_orig = NULL;
9310 	xodtemplate_timeperiod *next_timeperiod_orig = NULL;
9311 
9312 	/* sort all existing timeperiods */
9313 	for(temp_timeperiod_orig = xodtemplate_timeperiod_list; temp_timeperiod_orig != NULL; temp_timeperiod_orig = next_timeperiod_orig) {
9314 
9315 		next_timeperiod_orig = temp_timeperiod_orig->next;
9316 
9317 		/* add timeperiod to new list, sorted by timeperiod name */
9318 		last_timeperiod = new_timeperiod_list;
9319 		for(temp_timeperiod = new_timeperiod_list; temp_timeperiod != NULL; temp_timeperiod = temp_timeperiod->next) {
9320 
9321 			if(xodtemplate_compare_strings1(temp_timeperiod_orig->timeperiod_name, temp_timeperiod->timeperiod_name) <= 0)
9322 				break;
9323 			else
9324 				last_timeperiod = temp_timeperiod;
9325 			}
9326 
9327 		/* first item added to new sorted list */
9328 		if(new_timeperiod_list == NULL) {
9329 			temp_timeperiod_orig->next = NULL;
9330 			new_timeperiod_list = temp_timeperiod_orig;
9331 			}
9332 
9333 		/* item goes at head of new sorted list */
9334 		else if(temp_timeperiod == new_timeperiod_list) {
9335 			temp_timeperiod_orig->next = new_timeperiod_list;
9336 			new_timeperiod_list = temp_timeperiod_orig;
9337 			}
9338 
9339 		/* item goes in middle or at end of new sorted list */
9340 		else {
9341 			temp_timeperiod_orig->next = temp_timeperiod;
9342 			last_timeperiod->next = temp_timeperiod_orig;
9343 			}
9344 		}
9345 
9346 	/* list is now sorted */
9347 	xodtemplate_timeperiod_list = new_timeperiod_list;
9348 
9349 	return OK;
9350 	}
9351 
9352 
9353 /* sort commands by name */
xodtemplate_sort_commands()9354 int xodtemplate_sort_commands() {
9355 	xodtemplate_command *new_command_list = NULL;
9356 	xodtemplate_command *temp_command = NULL;
9357 	xodtemplate_command *last_command = NULL;
9358 	xodtemplate_command *temp_command_orig = NULL;
9359 	xodtemplate_command *next_command_orig = NULL;
9360 
9361 	/* sort all existing commands */
9362 	for(temp_command_orig = xodtemplate_command_list; temp_command_orig != NULL; temp_command_orig = next_command_orig) {
9363 
9364 		next_command_orig = temp_command_orig->next;
9365 
9366 		/* add command to new list, sorted by command name */
9367 		last_command = new_command_list;
9368 		for(temp_command = new_command_list; temp_command != NULL; temp_command = temp_command->next) {
9369 
9370 			if(xodtemplate_compare_strings1(temp_command_orig->command_name, temp_command->command_name) <= 0)
9371 				break;
9372 			else
9373 				last_command = temp_command;
9374 			}
9375 
9376 		/* first item added to new sorted list */
9377 		if(new_command_list == NULL) {
9378 			temp_command_orig->next = NULL;
9379 			new_command_list = temp_command_orig;
9380 			}
9381 
9382 		/* item goes at head of new sorted list */
9383 		else if(temp_command == new_command_list) {
9384 			temp_command_orig->next = new_command_list;
9385 			new_command_list = temp_command_orig;
9386 			}
9387 
9388 		/* item goes in middle or at end of new sorted list */
9389 		else {
9390 			temp_command_orig->next = temp_command;
9391 			last_command->next = temp_command_orig;
9392 			}
9393 		}
9394 
9395 	/* list is now sorted */
9396 	xodtemplate_command_list = new_command_list;
9397 
9398 	return OK;
9399 	}
9400 
9401 
9402 /* sort contactgroups by name */
xodtemplate_sort_contactgroups()9403 int xodtemplate_sort_contactgroups() {
9404 	xodtemplate_contactgroup *new_contactgroup_list = NULL;
9405 	xodtemplate_contactgroup *temp_contactgroup = NULL;
9406 	xodtemplate_contactgroup *last_contactgroup = NULL;
9407 	xodtemplate_contactgroup *temp_contactgroup_orig = NULL;
9408 	xodtemplate_contactgroup *next_contactgroup_orig = NULL;
9409 
9410 	/* sort all existing contactgroups */
9411 	for(temp_contactgroup_orig = xodtemplate_contactgroup_list; temp_contactgroup_orig != NULL; temp_contactgroup_orig = next_contactgroup_orig) {
9412 
9413 		next_contactgroup_orig = temp_contactgroup_orig->next;
9414 
9415 		/* add contactgroup to new list, sorted by contactgroup name */
9416 		last_contactgroup = new_contactgroup_list;
9417 		for(temp_contactgroup = new_contactgroup_list; temp_contactgroup != NULL; temp_contactgroup = temp_contactgroup->next) {
9418 
9419 			if(xodtemplate_compare_strings1(temp_contactgroup_orig->contactgroup_name, temp_contactgroup->contactgroup_name) <= 0)
9420 				break;
9421 			else
9422 				last_contactgroup = temp_contactgroup;
9423 			}
9424 
9425 		/* first item added to new sorted list */
9426 		if(new_contactgroup_list == NULL) {
9427 			temp_contactgroup_orig->next = NULL;
9428 			new_contactgroup_list = temp_contactgroup_orig;
9429 			}
9430 
9431 		/* item goes at head of new sorted list */
9432 		else if(temp_contactgroup == new_contactgroup_list) {
9433 			temp_contactgroup_orig->next = new_contactgroup_list;
9434 			new_contactgroup_list = temp_contactgroup_orig;
9435 			}
9436 
9437 		/* item goes in middle or at end of new sorted list */
9438 		else {
9439 			temp_contactgroup_orig->next = temp_contactgroup;
9440 			last_contactgroup->next = temp_contactgroup_orig;
9441 			}
9442 		}
9443 
9444 	/* list is now sorted */
9445 	xodtemplate_contactgroup_list = new_contactgroup_list;
9446 
9447 	return OK;
9448 	}
9449 
9450 
9451 /* sort hostgroups by name */
xodtemplate_sort_hostgroups()9452 int xodtemplate_sort_hostgroups() {
9453 	xodtemplate_hostgroup *new_hostgroup_list = NULL;
9454 	xodtemplate_hostgroup *temp_hostgroup = NULL;
9455 	xodtemplate_hostgroup *last_hostgroup = NULL;
9456 	xodtemplate_hostgroup *temp_hostgroup_orig = NULL;
9457 	xodtemplate_hostgroup *next_hostgroup_orig = NULL;
9458 
9459 	/* sort all existing hostgroups */
9460 	for(temp_hostgroup_orig = xodtemplate_hostgroup_list; temp_hostgroup_orig != NULL; temp_hostgroup_orig = next_hostgroup_orig) {
9461 
9462 		next_hostgroup_orig = temp_hostgroup_orig->next;
9463 
9464 		/* add hostgroup to new list, sorted by hostgroup name */
9465 		last_hostgroup = new_hostgroup_list;
9466 		for(temp_hostgroup = new_hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) {
9467 
9468 			if(xodtemplate_compare_strings1(temp_hostgroup_orig->hostgroup_name, temp_hostgroup->hostgroup_name) <= 0)
9469 				break;
9470 			else
9471 				last_hostgroup = temp_hostgroup;
9472 			}
9473 
9474 		/* first item added to new sorted list */
9475 		if(new_hostgroup_list == NULL) {
9476 			temp_hostgroup_orig->next = NULL;
9477 			new_hostgroup_list = temp_hostgroup_orig;
9478 			}
9479 
9480 		/* item goes at head of new sorted list */
9481 		else if(temp_hostgroup == new_hostgroup_list) {
9482 			temp_hostgroup_orig->next = new_hostgroup_list;
9483 			new_hostgroup_list = temp_hostgroup_orig;
9484 			}
9485 
9486 		/* item goes in middle or at end of new sorted list */
9487 		else {
9488 			temp_hostgroup_orig->next = temp_hostgroup;
9489 			last_hostgroup->next = temp_hostgroup_orig;
9490 			}
9491 		}
9492 
9493 	/* list is now sorted */
9494 	xodtemplate_hostgroup_list = new_hostgroup_list;
9495 
9496 	return OK;
9497 	}
9498 
9499 
9500 /* sort servicegroups by name */
xodtemplate_sort_servicegroups()9501 int xodtemplate_sort_servicegroups() {
9502 	xodtemplate_servicegroup *new_servicegroup_list = NULL;
9503 	xodtemplate_servicegroup *temp_servicegroup = NULL;
9504 	xodtemplate_servicegroup *last_servicegroup = NULL;
9505 	xodtemplate_servicegroup *temp_servicegroup_orig = NULL;
9506 	xodtemplate_servicegroup *next_servicegroup_orig = NULL;
9507 
9508 	/* sort all existing servicegroups */
9509 	for(temp_servicegroup_orig = xodtemplate_servicegroup_list; temp_servicegroup_orig != NULL; temp_servicegroup_orig = next_servicegroup_orig) {
9510 
9511 		next_servicegroup_orig = temp_servicegroup_orig->next;
9512 
9513 		/* add servicegroup to new list, sorted by servicegroup name */
9514 		last_servicegroup = new_servicegroup_list;
9515 		for(temp_servicegroup = new_servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) {
9516 
9517 			if(xodtemplate_compare_strings1(temp_servicegroup_orig->servicegroup_name, temp_servicegroup->servicegroup_name) <= 0)
9518 				break;
9519 			else
9520 				last_servicegroup = temp_servicegroup;
9521 			}
9522 
9523 		/* first item added to new sorted list */
9524 		if(new_servicegroup_list == NULL) {
9525 			temp_servicegroup_orig->next = NULL;
9526 			new_servicegroup_list = temp_servicegroup_orig;
9527 			}
9528 
9529 		/* item goes at head of new sorted list */
9530 		else if(temp_servicegroup == new_servicegroup_list) {
9531 			temp_servicegroup_orig->next = new_servicegroup_list;
9532 			new_servicegroup_list = temp_servicegroup_orig;
9533 			}
9534 
9535 		/* item goes in middle or at end of new sorted list */
9536 		else {
9537 			temp_servicegroup_orig->next = temp_servicegroup;
9538 			last_servicegroup->next = temp_servicegroup_orig;
9539 			}
9540 		}
9541 
9542 	/* list is now sorted */
9543 	xodtemplate_servicegroup_list = new_servicegroup_list;
9544 
9545 	return OK;
9546 	}
9547 
9548 
9549 /* sort contacts by name */
xodtemplate_sort_contacts()9550 int xodtemplate_sort_contacts() {
9551 	xodtemplate_contact *new_contact_list = NULL;
9552 	xodtemplate_contact *temp_contact = NULL;
9553 	xodtemplate_contact *last_contact = NULL;
9554 	xodtemplate_contact *temp_contact_orig = NULL;
9555 	xodtemplate_contact *next_contact_orig = NULL;
9556 
9557 	/* sort all existing contacts */
9558 	for(temp_contact_orig = xodtemplate_contact_list; temp_contact_orig != NULL; temp_contact_orig = next_contact_orig) {
9559 
9560 		next_contact_orig = temp_contact_orig->next;
9561 
9562 		/* add contact to new list, sorted by contact name */
9563 		last_contact = new_contact_list;
9564 		for(temp_contact = new_contact_list; temp_contact != NULL; temp_contact = temp_contact->next) {
9565 
9566 			if(xodtemplate_compare_strings1(temp_contact_orig->contact_name, temp_contact->contact_name) <= 0)
9567 				break;
9568 			else
9569 				last_contact = temp_contact;
9570 			}
9571 
9572 		/* first item added to new sorted list */
9573 		if(new_contact_list == NULL) {
9574 			temp_contact_orig->next = NULL;
9575 			new_contact_list = temp_contact_orig;
9576 			}
9577 
9578 		/* item goes at head of new sorted list */
9579 		else if(temp_contact == new_contact_list) {
9580 			temp_contact_orig->next = new_contact_list;
9581 			new_contact_list = temp_contact_orig;
9582 			}
9583 
9584 		/* item goes in middle or at end of new sorted list */
9585 		else {
9586 			temp_contact_orig->next = temp_contact;
9587 			last_contact->next = temp_contact_orig;
9588 			}
9589 		}
9590 
9591 	/* list is now sorted */
9592 	xodtemplate_contact_list = new_contact_list;
9593 
9594 	return OK;
9595 	}
9596 
9597 
xodtemplate_compare_host(void * arg1,void * arg2)9598 int xodtemplate_compare_host(void *arg1, void *arg2) {
9599 	xodtemplate_host *h1 = NULL;
9600 	xodtemplate_host *h2 = NULL;
9601 	int x = 0;
9602 
9603 	h1 = (xodtemplate_host *)arg1;
9604 	h2 = (xodtemplate_host *)arg2;
9605 
9606 	if(h1 == NULL && h2 == NULL)
9607 		return 0;
9608 	if(h1 == NULL)
9609 		return 1;
9610 	if(h2 == NULL)
9611 		return -1;
9612 
9613 	x = strcmp((h1->host_name == NULL) ? "" : h1->host_name, (h2->host_name == NULL) ? "" : h2->host_name);
9614 
9615 	return x;
9616 	}
9617 
9618 
9619 
9620 /* sort hosts by name */
xodtemplate_sort_hosts()9621 int xodtemplate_sort_hosts() {
9622 #ifdef NEWSTUFF
9623 	xodtemplate_host *temp_host = NULL;
9624 
9625 	/* initialize a new skip list */
9626 	if((xodtemplate_host_skiplist = skiplist_new(15, 0.5, FALSE, xodtemplate_compare_host)) == NULL)
9627 		return ERROR;
9628 
9629 	/* add all hosts to skip list */
9630 	for(temp_host = xodtemplate_host_list; temp_host != NULL; temp_host = temp_host->next)
9631 		skiplist_insert(xodtemplate_host_skiplist, temp_host);
9632 	/*printf("SKIPLIST ITEMS: %lu\n",xodtemplate_host_skiplist->items);*/
9633 
9634 	/* now move items from skiplist to linked list... */
9635 	/* TODO */
9636 #endif
9637 
9638 	xodtemplate_host *new_host_list = NULL;
9639 	xodtemplate_host *temp_host = NULL;
9640 	xodtemplate_host *last_host = NULL;
9641 	xodtemplate_host *temp_host_orig = NULL;
9642 	xodtemplate_host *next_host_orig = NULL;
9643 
9644 	/* sort all existing hosts */
9645 	for(temp_host_orig = xodtemplate_host_list; temp_host_orig != NULL; temp_host_orig = next_host_orig) {
9646 
9647 		next_host_orig = temp_host_orig->next;
9648 
9649 		/* add host to new list, sorted by host name */
9650 		last_host = new_host_list;
9651 		for(temp_host = new_host_list; temp_host != NULL; temp_host = temp_host->next) {
9652 
9653 			if(xodtemplate_compare_strings1(temp_host_orig->host_name, temp_host->host_name) <= 0)
9654 				break;
9655 			else
9656 				last_host = temp_host;
9657 			}
9658 
9659 		/* first item added to new sorted list */
9660 		if(new_host_list == NULL) {
9661 			temp_host_orig->next = NULL;
9662 			new_host_list = temp_host_orig;
9663 			}
9664 
9665 		/* item goes at head of new sorted list */
9666 		else if(temp_host == new_host_list) {
9667 			temp_host_orig->next = new_host_list;
9668 			new_host_list = temp_host_orig;
9669 			}
9670 
9671 		/* item goes in middle or at end of new sorted list */
9672 		else {
9673 			temp_host_orig->next = temp_host;
9674 			last_host->next = temp_host_orig;
9675 			}
9676 		}
9677 
9678 	/* list is now sorted */
9679 	xodtemplate_host_list = new_host_list;
9680 
9681 	return OK;
9682 	}
9683 
9684 
xodtemplate_compare_service(void * arg1,void * arg2)9685 int xodtemplate_compare_service(void *arg1, void *arg2) {
9686 	xodtemplate_service *s1 = NULL;
9687 	xodtemplate_service *s2 = NULL;
9688 	int x = 0;
9689 
9690 	s1 = (xodtemplate_service *)arg1;
9691 	s2 = (xodtemplate_service *)arg2;
9692 
9693 	if(s1 == NULL && s2 == NULL)
9694 		return 0;
9695 	if(s1 == NULL)
9696 		return 1;
9697 	if(s2 == NULL)
9698 		return -1;
9699 
9700 	x = strcmp((s1->host_name == NULL) ? "" : s1->host_name, (s2->host_name == NULL) ? "" : s2->host_name);
9701 	if(x == 0)
9702 		x = strcmp((s1->service_description == NULL) ? "" : s1->service_description, (s2->service_description == NULL) ? "" : s2->service_description);
9703 
9704 	return x;
9705 	}
9706 
9707 
9708 /* sort services by name */
xodtemplate_sort_services()9709 int xodtemplate_sort_services() {
9710 #ifdef NEWSTUFF
9711 	xodtemplate_service *temp_service = NULL;
9712 
9713 	/* initialize a new skip list */
9714 	if((xodtemplate_service_skiplist = skiplist_new(15, 0.5, FALSE, xodtemplate_compare_service)) == NULL)
9715 		return ERROR;
9716 
9717 	/* add all services to skip list */
9718 	for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next)
9719 		skiplist_insert(xodtemplate_service_skiplist, temp_service);
9720 	/*printf("SKIPLIST ITEMS: %lu\n",xodtemplate_service_skiplist->items);*/
9721 
9722 	/* now move items to linked list... */
9723 	/* TODO */
9724 #endif
9725 
9726 	xodtemplate_service *new_service_list = NULL;
9727 	xodtemplate_service *temp_service = NULL;
9728 	xodtemplate_service *last_service = NULL;
9729 	xodtemplate_service *temp_service_orig = NULL;
9730 	xodtemplate_service *next_service_orig = NULL;
9731 
9732 	/* sort all existing services */
9733 	for(temp_service_orig = xodtemplate_service_list; temp_service_orig != NULL; temp_service_orig = next_service_orig) {
9734 
9735 		next_service_orig = temp_service_orig->next;
9736 
9737 		/* add service to new list, sorted by host name then service description */
9738 		last_service = new_service_list;
9739 		for(temp_service = new_service_list; temp_service != NULL; temp_service = temp_service->next) {
9740 
9741 			if(xodtemplate_compare_strings2(temp_service_orig->host_name, temp_service_orig->service_description, temp_service->host_name, temp_service->service_description) <= 0)
9742 				break;
9743 			else
9744 				last_service = temp_service;
9745 			}
9746 
9747 		/* first item added to new sorted list */
9748 		if(new_service_list == NULL) {
9749 			temp_service_orig->next = NULL;
9750 			new_service_list = temp_service_orig;
9751 			}
9752 
9753 		/* item goes at head of new sorted list */
9754 		else if(temp_service == new_service_list) {
9755 			temp_service_orig->next = new_service_list;
9756 			new_service_list = temp_service_orig;
9757 			}
9758 
9759 		/* item goes in middle or at end of new sorted list */
9760 		else {
9761 			temp_service_orig->next = temp_service;
9762 			last_service->next = temp_service_orig;
9763 			}
9764 		}
9765 
9766 	/* list is now sorted */
9767 	xodtemplate_service_list = new_service_list;
9768 
9769 	return OK;
9770 	}
9771 
9772 
9773 /* sort servicedependencies by name */
xodtemplate_sort_servicedependencies()9774 int xodtemplate_sort_servicedependencies() {
9775 	xodtemplate_servicedependency *new_servicedependency_list = NULL;
9776 	xodtemplate_servicedependency *temp_servicedependency = NULL;
9777 	xodtemplate_servicedependency *last_servicedependency = NULL;
9778 	xodtemplate_servicedependency *temp_servicedependency_orig = NULL;
9779 	xodtemplate_servicedependency *next_servicedependency_orig = NULL;
9780 
9781 	/* sort all existing servicedependencies */
9782 	for(temp_servicedependency_orig = xodtemplate_servicedependency_list; temp_servicedependency_orig != NULL; temp_servicedependency_orig = next_servicedependency_orig) {
9783 
9784 		next_servicedependency_orig = temp_servicedependency_orig->next;
9785 
9786 		/* add servicedependency to new list, sorted by host name then service description */
9787 		last_servicedependency = new_servicedependency_list;
9788 		for(temp_servicedependency = new_servicedependency_list; temp_servicedependency != NULL; temp_servicedependency = temp_servicedependency->next) {
9789 
9790 			if(xodtemplate_compare_strings2(temp_servicedependency_orig->host_name, temp_servicedependency_orig->service_description, temp_servicedependency->host_name, temp_servicedependency->service_description) <= 0)
9791 				break;
9792 			else
9793 				last_servicedependency = temp_servicedependency;
9794 			}
9795 
9796 		/* first item added to new sorted list */
9797 		if(new_servicedependency_list == NULL) {
9798 			temp_servicedependency_orig->next = NULL;
9799 			new_servicedependency_list = temp_servicedependency_orig;
9800 			}
9801 
9802 		/* item goes at head of new sorted list */
9803 		else if(temp_servicedependency == new_servicedependency_list) {
9804 			temp_servicedependency_orig->next = new_servicedependency_list;
9805 			new_servicedependency_list = temp_servicedependency_orig;
9806 			}
9807 
9808 		/* item goes in middle or at end of new sorted list */
9809 		else {
9810 			temp_servicedependency_orig->next = temp_servicedependency;
9811 			last_servicedependency->next = temp_servicedependency_orig;
9812 			}
9813 		}
9814 
9815 	/* list is now sorted */
9816 	xodtemplate_servicedependency_list = new_servicedependency_list;
9817 
9818 	return OK;
9819 	}
9820 
9821 
9822 /* sort serviceescalations by name */
xodtemplate_sort_serviceescalations()9823 int xodtemplate_sort_serviceescalations() {
9824 	xodtemplate_serviceescalation *new_serviceescalation_list = NULL;
9825 	xodtemplate_serviceescalation *temp_serviceescalation = NULL;
9826 	xodtemplate_serviceescalation *last_serviceescalation = NULL;
9827 	xodtemplate_serviceescalation *temp_serviceescalation_orig = NULL;
9828 	xodtemplate_serviceescalation *next_serviceescalation_orig = NULL;
9829 
9830 	/* sort all existing serviceescalations */
9831 	for(temp_serviceescalation_orig = xodtemplate_serviceescalation_list; temp_serviceescalation_orig != NULL; temp_serviceescalation_orig = next_serviceescalation_orig) {
9832 
9833 		next_serviceescalation_orig = temp_serviceescalation_orig->next;
9834 
9835 		/* add serviceescalation to new list, sorted by host name then service description */
9836 		last_serviceescalation = new_serviceescalation_list;
9837 		for(temp_serviceescalation = new_serviceescalation_list; temp_serviceescalation != NULL; temp_serviceescalation = temp_serviceescalation->next) {
9838 
9839 			if(xodtemplate_compare_strings2(temp_serviceescalation_orig->host_name, temp_serviceescalation_orig->service_description, temp_serviceescalation->host_name, temp_serviceescalation->service_description) <= 0)
9840 				break;
9841 			else
9842 				last_serviceescalation = temp_serviceescalation;
9843 			}
9844 
9845 		/* first item added to new sorted list */
9846 		if(new_serviceescalation_list == NULL) {
9847 			temp_serviceescalation_orig->next = NULL;
9848 			new_serviceescalation_list = temp_serviceescalation_orig;
9849 			}
9850 
9851 		/* item goes at head of new sorted list */
9852 		else if(temp_serviceescalation == new_serviceescalation_list) {
9853 			temp_serviceescalation_orig->next = new_serviceescalation_list;
9854 			new_serviceescalation_list = temp_serviceescalation_orig;
9855 			}
9856 
9857 		/* item goes in middle or at end of new sorted list */
9858 		else {
9859 			temp_serviceescalation_orig->next = temp_serviceescalation;
9860 			last_serviceescalation->next = temp_serviceescalation_orig;
9861 			}
9862 		}
9863 
9864 	/* list is now sorted */
9865 	xodtemplate_serviceescalation_list = new_serviceescalation_list;
9866 
9867 	return OK;
9868 	}
9869 
9870 
9871 /* sort hostescalations by name */
xodtemplate_sort_hostescalations()9872 int xodtemplate_sort_hostescalations() {
9873 	xodtemplate_hostescalation *new_hostescalation_list = NULL;
9874 	xodtemplate_hostescalation *temp_hostescalation = NULL;
9875 	xodtemplate_hostescalation *last_hostescalation = NULL;
9876 	xodtemplate_hostescalation *temp_hostescalation_orig = NULL;
9877 	xodtemplate_hostescalation *next_hostescalation_orig = NULL;
9878 
9879 	/* sort all existing hostescalations */
9880 	for(temp_hostescalation_orig = xodtemplate_hostescalation_list; temp_hostescalation_orig != NULL; temp_hostescalation_orig = next_hostescalation_orig) {
9881 
9882 		next_hostescalation_orig = temp_hostescalation_orig->next;
9883 
9884 		/* add hostescalation to new list, sorted by host name then hostescalation description */
9885 		last_hostescalation = new_hostescalation_list;
9886 		for(temp_hostescalation = new_hostescalation_list; temp_hostescalation != NULL; temp_hostescalation = temp_hostescalation->next) {
9887 
9888 			if(xodtemplate_compare_strings1(temp_hostescalation_orig->host_name, temp_hostescalation->host_name) <= 0)
9889 				break;
9890 			else
9891 				last_hostescalation = temp_hostescalation;
9892 			}
9893 
9894 		/* first item added to new sorted list */
9895 		if(new_hostescalation_list == NULL) {
9896 			temp_hostescalation_orig->next = NULL;
9897 			new_hostescalation_list = temp_hostescalation_orig;
9898 			}
9899 
9900 		/* item goes at head of new sorted list */
9901 		else if(temp_hostescalation == new_hostescalation_list) {
9902 			temp_hostescalation_orig->next = new_hostescalation_list;
9903 			new_hostescalation_list = temp_hostescalation_orig;
9904 			}
9905 
9906 		/* item goes in middle or at end of new sorted list */
9907 		else {
9908 			temp_hostescalation_orig->next = temp_hostescalation;
9909 			last_hostescalation->next = temp_hostescalation_orig;
9910 			}
9911 		}
9912 
9913 	/* list is now sorted */
9914 	xodtemplate_hostescalation_list = new_hostescalation_list;
9915 
9916 	return OK;
9917 	}
9918 
9919 
9920 /* sort hostdependencies by name */
xodtemplate_sort_hostdependencies()9921 int xodtemplate_sort_hostdependencies() {
9922 	xodtemplate_hostdependency *new_hostdependency_list = NULL;
9923 	xodtemplate_hostdependency *temp_hostdependency = NULL;
9924 	xodtemplate_hostdependency *last_hostdependency = NULL;
9925 	xodtemplate_hostdependency *temp_hostdependency_orig = NULL;
9926 	xodtemplate_hostdependency *next_hostdependency_orig = NULL;
9927 
9928 	/* sort all existing hostdependencys */
9929 	for(temp_hostdependency_orig = xodtemplate_hostdependency_list; temp_hostdependency_orig != NULL; temp_hostdependency_orig = next_hostdependency_orig) {
9930 
9931 		next_hostdependency_orig = temp_hostdependency_orig->next;
9932 
9933 		/* add hostdependency to new list, sorted by host name then hostdependency description */
9934 		last_hostdependency = new_hostdependency_list;
9935 		for(temp_hostdependency = new_hostdependency_list; temp_hostdependency != NULL; temp_hostdependency = temp_hostdependency->next) {
9936 
9937 			if(xodtemplate_compare_strings1(temp_hostdependency_orig->host_name, temp_hostdependency->host_name) <= 0)
9938 				break;
9939 			else
9940 				last_hostdependency = temp_hostdependency;
9941 			}
9942 
9943 		/* first item added to new sorted list */
9944 		if(new_hostdependency_list == NULL) {
9945 			temp_hostdependency_orig->next = NULL;
9946 			new_hostdependency_list = temp_hostdependency_orig;
9947 			}
9948 
9949 		/* item goes at head of new sorted list */
9950 		else if(temp_hostdependency == new_hostdependency_list) {
9951 			temp_hostdependency_orig->next = new_hostdependency_list;
9952 			new_hostdependency_list = temp_hostdependency_orig;
9953 			}
9954 
9955 		/* item goes in middle or at end of new sorted list */
9956 		else {
9957 			temp_hostdependency_orig->next = temp_hostdependency;
9958 			last_hostdependency->next = temp_hostdependency_orig;
9959 			}
9960 		}
9961 
9962 	/* list is now sorted */
9963 	xodtemplate_hostdependency_list = new_hostdependency_list;
9964 
9965 	return OK;
9966 	}
9967 
9968 #endif
9969 
9970 
9971 
9972 
9973 /******************************************************************/
9974 /*********************** MERGE FUNCTIONS **************************/
9975 /******************************************************************/
9976 
9977 #ifdef NSCORE
9978 
9979 /* merge extinfo definitions */
xodtemplate_merge_extinfo_ojects(void)9980 int xodtemplate_merge_extinfo_ojects(void) {
9981 	xodtemplate_hostextinfo *temp_hostextinfo = NULL;
9982 	xodtemplate_serviceextinfo *temp_serviceextinfo = NULL;
9983 	xodtemplate_host *temp_host = NULL;
9984 	xodtemplate_service *temp_service = NULL;
9985 
9986 	/* merge service extinfo definitions */
9987 	for(temp_serviceextinfo = xodtemplate_serviceextinfo_list; temp_serviceextinfo != NULL; temp_serviceextinfo = temp_serviceextinfo->next) {
9988 
9989 		/* make sure we have everything */
9990 		if(temp_serviceextinfo->host_name == NULL || temp_serviceextinfo->service_description == NULL)
9991 			continue;
9992 
9993 		/* find the service */
9994 		if((temp_service = xodtemplate_find_real_service(temp_serviceextinfo->host_name, temp_serviceextinfo->service_description)) == NULL)
9995 			continue;
9996 
9997 		/* merge the definitions */
9998 		xodtemplate_merge_service_extinfo_object(temp_service, temp_serviceextinfo);
9999 		}
10000 
10001 	/* merge host extinfo definitions */
10002 	for(temp_hostextinfo = xodtemplate_hostextinfo_list; temp_hostextinfo != NULL; temp_hostextinfo = temp_hostextinfo->next) {
10003 
10004 		/* make sure we have everything */
10005 		if(temp_hostextinfo->host_name == NULL)
10006 			continue;
10007 
10008 		/* find the host */
10009 		if((temp_host = xodtemplate_find_real_host(temp_hostextinfo->host_name)) == NULL)
10010 			continue;
10011 
10012 		/* merge the definitions */
10013 		xodtemplate_merge_host_extinfo_object(temp_host, temp_hostextinfo);
10014 		}
10015 
10016 	return OK;
10017 	}
10018 
10019 
10020 /* merges a service extinfo definition */
xodtemplate_merge_service_extinfo_object(xodtemplate_service * this_service,xodtemplate_serviceextinfo * this_serviceextinfo)10021 int xodtemplate_merge_service_extinfo_object(xodtemplate_service *this_service, xodtemplate_serviceextinfo *this_serviceextinfo) {
10022 
10023 	if(this_service == NULL || this_serviceextinfo == NULL)
10024 		return ERROR;
10025 
10026 	if(this_service->notes == NULL && this_serviceextinfo->notes != NULL)
10027 		this_service->notes = strdup(this_serviceextinfo->notes);
10028 	if(this_service->notes_url == NULL && this_serviceextinfo->notes_url != NULL)
10029 		this_service->notes_url = strdup(this_serviceextinfo->notes_url);
10030 	if(this_service->action_url == NULL && this_serviceextinfo->action_url != NULL)
10031 		this_service->action_url = strdup(this_serviceextinfo->action_url);
10032 	if(this_service->icon_image == NULL && this_serviceextinfo->icon_image != NULL)
10033 		this_service->icon_image = strdup(this_serviceextinfo->icon_image);
10034 	if(this_service->icon_image_alt == NULL && this_serviceextinfo->icon_image_alt != NULL)
10035 		this_service->icon_image_alt = strdup(this_serviceextinfo->icon_image_alt);
10036 
10037 	return OK;
10038 	}
10039 
10040 
10041 /* merges a host extinfo definition */
xodtemplate_merge_host_extinfo_object(xodtemplate_host * this_host,xodtemplate_hostextinfo * this_hostextinfo)10042 int xodtemplate_merge_host_extinfo_object(xodtemplate_host *this_host, xodtemplate_hostextinfo *this_hostextinfo) {
10043 
10044 	if(this_host == NULL || this_hostextinfo == NULL)
10045 		return ERROR;
10046 
10047 	if(this_host->notes == NULL && this_hostextinfo->notes != NULL)
10048 		this_host->notes = strdup(this_hostextinfo->notes);
10049 	if(this_host->notes_url == NULL && this_hostextinfo->notes_url != NULL)
10050 		this_host->notes_url = strdup(this_hostextinfo->notes_url);
10051 	if(this_host->action_url == NULL && this_hostextinfo->action_url != NULL)
10052 		this_host->action_url = strdup(this_hostextinfo->action_url);
10053 	if(this_host->icon_image == NULL && this_hostextinfo->icon_image != NULL)
10054 		this_host->icon_image = strdup(this_hostextinfo->icon_image);
10055 	if(this_host->icon_image_alt == NULL && this_hostextinfo->icon_image_alt != NULL)
10056 		this_host->icon_image_alt = strdup(this_hostextinfo->icon_image_alt);
10057 	if(this_host->vrml_image == NULL && this_hostextinfo->vrml_image != NULL)
10058 		this_host->vrml_image = strdup(this_hostextinfo->vrml_image);
10059 	if(this_host->statusmap_image == NULL && this_hostextinfo->statusmap_image != NULL)
10060 		this_host->statusmap_image = strdup(this_hostextinfo->statusmap_image);
10061 
10062 	if(this_host->have_2d_coords == FALSE && this_hostextinfo->have_2d_coords == TRUE) {
10063 		this_host->x_2d = this_hostextinfo->x_2d;
10064 		this_host->y_2d = this_hostextinfo->y_2d;
10065 		this_host->have_2d_coords = TRUE;
10066 		}
10067 	if(this_host->have_3d_coords == FALSE && this_hostextinfo->have_3d_coords == TRUE) {
10068 		this_host->x_3d = this_hostextinfo->x_3d;
10069 		this_host->y_3d = this_hostextinfo->y_3d;
10070 		this_host->z_3d = this_hostextinfo->z_3d;
10071 		this_host->have_3d_coords = TRUE;
10072 		}
10073 
10074 	return OK;
10075 	}
10076 
10077 #endif
10078 
10079 
10080 
10081 /******************************************************************/
10082 /*********************** CACHE FUNCTIONS **************************/
10083 /******************************************************************/
10084 
10085 #ifdef NSCORE
10086 
10087 /* writes cached object definitions for use by web interface */
xodtemplate_cache_objects(char * cache_file)10088 int xodtemplate_cache_objects(char *cache_file) {
10089 	FILE *fp = NULL;
10090 	register int x = 0;
10091 	char *days[7] = {"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"};
10092 	char *months[12] = {"january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"};
10093 	xodtemplate_timeperiod *temp_timeperiod = NULL;
10094 	xodtemplate_daterange *temp_daterange = NULL;
10095 	xodtemplate_command *temp_command = NULL;
10096 	xodtemplate_contactgroup *temp_contactgroup = NULL;
10097 	xodtemplate_hostgroup *temp_hostgroup = NULL;
10098 	xodtemplate_servicegroup *temp_servicegroup = NULL;
10099 	xodtemplate_contact *temp_contact = NULL;
10100 	xodtemplate_host *temp_host = NULL;
10101 	xodtemplate_service *temp_service = NULL;
10102 	xodtemplate_servicedependency *temp_servicedependency = NULL;
10103 	xodtemplate_serviceescalation *temp_serviceescalation = NULL;
10104 	xodtemplate_hostdependency *temp_hostdependency = NULL;
10105 	xodtemplate_hostescalation *temp_hostescalation = NULL;
10106 	xodtemplate_customvariablesmember *temp_customvariablesmember = NULL;
10107 	time_t current_time = 0L;
10108 	void *ptr = NULL;
10109 
10110 
10111 	time(&current_time);
10112 
10113 	/* open the cache file for writing */
10114 	fp = fopen(cache_file, "w");
10115 	if(fp == NULL) {
10116 		logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Could not open object cache file '%s' for writing!\n", cache_file);
10117 		return ERROR;
10118 		}
10119 
10120 	/* write header to cache file */
10121 	fprintf(fp, "########################################\n");
10122 	fprintf(fp, "#       NAGIOS OBJECT CACHE FILE\n");
10123 	fprintf(fp, "#\n");
10124 	fprintf(fp, "# THIS FILE IS AUTOMATICALLY GENERATED\n");
10125 	fprintf(fp, "# BY NAGIOS.  DO NOT MODIFY THIS FILE!\n");
10126 	fprintf(fp, "#\n");
10127 	fprintf(fp, "# Created: %s", ctime(&current_time));
10128 	fprintf(fp, "########################################\n\n");
10129 
10130 
10131 	/* cache timeperiods */
10132 	/*for(temp_timeperiod=xodtemplate_timeperiod_list;temp_timeperiod!=NULL;temp_timeperiod=temp_timeperiod->next){*/
10133 	ptr = NULL;
10134 	for(temp_timeperiod = (xodtemplate_timeperiod *)skiplist_get_first(xobject_skiplists[X_TIMEPERIOD_SKIPLIST], &ptr); temp_timeperiod != NULL; temp_timeperiod = (xodtemplate_timeperiod *)skiplist_get_next(&ptr)) {
10135 
10136 		if(temp_timeperiod->register_object == FALSE)
10137 			continue;
10138 		fprintf(fp, "define timeperiod {\n");
10139 		if(temp_timeperiod->timeperiod_name)
10140 			fprintf(fp, "\ttimeperiod_name\t%s\n", temp_timeperiod->timeperiod_name);
10141 		if(temp_timeperiod->alias)
10142 			fprintf(fp, "\talias\t%s\n", temp_timeperiod->alias);
10143 		for(x = 0; x < DATERANGE_TYPES; x++) {
10144 			for(temp_daterange = temp_timeperiod->exceptions[x]; temp_daterange != NULL; temp_daterange = temp_daterange->next) {
10145 
10146 				/* skip null entries */
10147 				if(temp_daterange->timeranges == NULL || !strcmp(temp_daterange->timeranges, XODTEMPLATE_NULL))
10148 					continue;
10149 
10150 				switch(temp_daterange->type) {
10151 					case DATERANGE_CALENDAR_DATE:
10152 						fprintf(fp, "\t%d-%02d-%02d", temp_daterange->syear, temp_daterange->smon + 1, temp_daterange->smday);
10153 						if((temp_daterange->smday != temp_daterange->emday) || (temp_daterange->smon != temp_daterange->emon) || (temp_daterange->syear != temp_daterange->eyear))
10154 							fprintf(fp, " - %d-%02d-%02d", temp_daterange->eyear, temp_daterange->emon + 1, temp_daterange->emday);
10155 						if(temp_daterange->skip_interval > 1)
10156 							fprintf(fp, " / %d", temp_daterange->skip_interval);
10157 						break;
10158 					case DATERANGE_MONTH_DATE:
10159 						fprintf(fp, "\t%s %d", months[temp_daterange->smon], temp_daterange->smday);
10160 						if((temp_daterange->smon != temp_daterange->emon) || (temp_daterange->smday != temp_daterange->emday)) {
10161 							fprintf(fp, " - %s %d", months[temp_daterange->emon], temp_daterange->emday);
10162 							if(temp_daterange->skip_interval > 1)
10163 								fprintf(fp, " / %d", temp_daterange->skip_interval);
10164 							}
10165 						break;
10166 					case DATERANGE_MONTH_DAY:
10167 						fprintf(fp, "\tday %d", temp_daterange->smday);
10168 						if(temp_daterange->smday != temp_daterange->emday) {
10169 							fprintf(fp, " - %d", temp_daterange->emday);
10170 							if(temp_daterange->skip_interval > 1)
10171 								fprintf(fp, " / %d", temp_daterange->skip_interval);
10172 							}
10173 						break;
10174 					case DATERANGE_MONTH_WEEK_DAY:
10175 						fprintf(fp, "\t%s %d %s", days[temp_daterange->swday], temp_daterange->swday_offset, months[temp_daterange->smon]);
10176 						if((temp_daterange->smon != temp_daterange->emon) || (temp_daterange->swday != temp_daterange->ewday) || (temp_daterange->swday_offset != temp_daterange->ewday_offset)) {
10177 							fprintf(fp, " - %s %d %s", days[temp_daterange->ewday], temp_daterange->ewday_offset, months[temp_daterange->emon]);
10178 							if(temp_daterange->skip_interval > 1)
10179 								fprintf(fp, " / %d", temp_daterange->skip_interval);
10180 							}
10181 						break;
10182 					case DATERANGE_WEEK_DAY:
10183 						fprintf(fp, "\t%s %d", days[temp_daterange->swday], temp_daterange->swday_offset);
10184 						if((temp_daterange->swday != temp_daterange->ewday) || (temp_daterange->swday_offset != temp_daterange->ewday_offset)) {
10185 							fprintf(fp, " - %s %d", days[temp_daterange->ewday], temp_daterange->ewday_offset);
10186 							if(temp_daterange->skip_interval > 1)
10187 								fprintf(fp, " / %d", temp_daterange->skip_interval);
10188 							}
10189 						break;
10190 					default:
10191 						break;
10192 					}
10193 
10194 				fprintf(fp, "\t%s\n", temp_daterange->timeranges);
10195 				}
10196 			}
10197 		for(x = 0; x < 7; x++) {
10198 			/* skip null entries */
10199 			if(temp_timeperiod->timeranges[x] == NULL  || !strcmp(temp_timeperiod->timeranges[x], XODTEMPLATE_NULL))
10200 				continue;
10201 
10202 			fprintf(fp, "\t%s\t%s\n", days[x], temp_timeperiod->timeranges[x]);
10203 			}
10204 		if(temp_timeperiod->exclusions)
10205 			fprintf(fp, "\texclude\t%s\n", temp_timeperiod->exclusions);
10206 		fprintf(fp, "\t}\n\n");
10207 		}
10208 
10209 	/* cache commands */
10210 	/*for(temp_command=xodtemplate_command_list;temp_command!=NULL;temp_command=temp_command->next){*/
10211 	ptr = NULL;
10212 	for(temp_command = (xodtemplate_command *)skiplist_get_first(xobject_skiplists[X_COMMAND_SKIPLIST], &ptr); temp_command != NULL; temp_command = (xodtemplate_command *)skiplist_get_next(&ptr)) {
10213 		if(temp_command->register_object == FALSE)
10214 			continue;
10215 		fprintf(fp, "define command {\n");
10216 		if(temp_command->command_name)
10217 			fprintf(fp, "\tcommand_name\t%s\n", temp_command->command_name);
10218 		if(temp_command->command_line)
10219 			fprintf(fp, "\tcommand_line\t%s\n", temp_command->command_line);
10220 		fprintf(fp, "\t}\n\n");
10221 		}
10222 
10223 	/* cache contactgroups */
10224 	/*for(temp_contactgroup=xodtemplate_contactgroup_list;temp_contactgroup!=NULL;temp_contactgroup=temp_contactgroup->next){*/
10225 	ptr = NULL;
10226 	for(temp_contactgroup = (xodtemplate_contactgroup *)skiplist_get_first(xobject_skiplists[X_CONTACTGROUP_SKIPLIST], &ptr); temp_contactgroup != NULL; temp_contactgroup = (xodtemplate_contactgroup *)skiplist_get_next(&ptr)) {
10227 		if(temp_contactgroup->register_object == FALSE)
10228 			continue;
10229 		fprintf(fp, "define contactgroup {\n");
10230 		if(temp_contactgroup->contactgroup_name)
10231 			fprintf(fp, "\tcontactgroup_name\t%s\n", temp_contactgroup->contactgroup_name);
10232 		if(temp_contactgroup->alias)
10233 			fprintf(fp, "\talias\t%s\n", temp_contactgroup->alias);
10234 		if(temp_contactgroup->members)
10235 			fprintf(fp, "\tmembers\t%s\n", temp_contactgroup->members);
10236 		fprintf(fp, "\t}\n\n");
10237 		}
10238 
10239 	/* cache hostgroups */
10240 	/*for(temp_hostgroup=xodtemplate_hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){*/
10241 	ptr = NULL;
10242 	for(temp_hostgroup = (xodtemplate_hostgroup *)skiplist_get_first(xobject_skiplists[X_HOSTGROUP_SKIPLIST], &ptr); temp_hostgroup != NULL; temp_hostgroup = (xodtemplate_hostgroup *)skiplist_get_next(&ptr)) {
10243 		if(temp_hostgroup->register_object == FALSE)
10244 			continue;
10245 		fprintf(fp, "define hostgroup {\n");
10246 		if(temp_hostgroup->hostgroup_name)
10247 			fprintf(fp, "\thostgroup_name\t%s\n", temp_hostgroup->hostgroup_name);
10248 		if(temp_hostgroup->alias)
10249 			fprintf(fp, "\talias\t%s\n", temp_hostgroup->alias);
10250 		if(temp_hostgroup->members)
10251 			fprintf(fp, "\tmembers\t%s\n", temp_hostgroup->members);
10252 		if(temp_hostgroup->notes)
10253 			fprintf(fp, "\tnotes\t%s\n", temp_hostgroup->notes);
10254 		if(temp_hostgroup->notes_url)
10255 			fprintf(fp, "\tnotes_url\t%s\n", temp_hostgroup->notes_url);
10256 		if(temp_hostgroup->action_url)
10257 			fprintf(fp, "\taction_url\t%s\n", temp_hostgroup->action_url);
10258 		fprintf(fp, "\t}\n\n");
10259 		}
10260 
10261 	/* cache servicegroups */
10262 	/*for(temp_servicegroup=xodtemplate_servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next){*/
10263 	ptr = NULL;
10264 	for(temp_servicegroup = (xodtemplate_servicegroup *)skiplist_get_first(xobject_skiplists[X_SERVICEGROUP_SKIPLIST], &ptr); temp_servicegroup != NULL; temp_servicegroup = (xodtemplate_servicegroup *)skiplist_get_next(&ptr)) {
10265 		if(temp_servicegroup->register_object == FALSE)
10266 			continue;
10267 		fprintf(fp, "define servicegroup {\n");
10268 		if(temp_servicegroup->servicegroup_name)
10269 			fprintf(fp, "\tservicegroup_name\t%s\n", temp_servicegroup->servicegroup_name);
10270 		if(temp_servicegroup->alias)
10271 			fprintf(fp, "\talias\t%s\n", temp_servicegroup->alias);
10272 		if(temp_servicegroup->members)
10273 			fprintf(fp, "\tmembers\t%s\n", temp_servicegroup->members);
10274 		if(temp_servicegroup->notes)
10275 			fprintf(fp, "\tnotes\t%s\n", temp_servicegroup->notes);
10276 		if(temp_servicegroup->notes_url)
10277 			fprintf(fp, "\tnotes_url\t%s\n", temp_servicegroup->notes_url);
10278 		if(temp_servicegroup->action_url)
10279 			fprintf(fp, "\taction_url\t%s\n", temp_servicegroup->action_url);
10280 		fprintf(fp, "\t}\n\n");
10281 		}
10282 
10283 	/* cache contacts */
10284 	/*for(temp_contact=xodtemplate_contact_list;temp_contact!=NULL;temp_contact=temp_contact->next){*/
10285 	ptr = NULL;
10286 	for(temp_contact = (xodtemplate_contact *)skiplist_get_first(xobject_skiplists[X_CONTACT_SKIPLIST], &ptr); temp_contact != NULL; temp_contact = (xodtemplate_contact *)skiplist_get_next(&ptr)) {
10287 		if(temp_contact->register_object == FALSE)
10288 			continue;
10289 		fprintf(fp, "define contact {\n");
10290 		if(temp_contact->contact_name)
10291 			fprintf(fp, "\tcontact_name\t%s\n", temp_contact->contact_name);
10292 		if(temp_contact->alias)
10293 			fprintf(fp, "\talias\t%s\n", temp_contact->alias);
10294 		if(temp_contact->service_notification_period)
10295 			fprintf(fp, "\tservice_notification_period\t%s\n", temp_contact->service_notification_period);
10296 		if(temp_contact->host_notification_period)
10297 			fprintf(fp, "\thost_notification_period\t%s\n", temp_contact->host_notification_period);
10298 		fprintf(fp, "\tservice_notification_options\t");
10299 		x = 0;
10300 		if(temp_contact->notify_on_service_warning == TRUE)
10301 			fprintf(fp, "%sw", (x++ > 0) ? "," : "");
10302 		if(temp_contact->notify_on_service_unknown == TRUE)
10303 			fprintf(fp, "%su", (x++ > 0) ? "," : "");
10304 		if(temp_contact->notify_on_service_critical == TRUE)
10305 			fprintf(fp, "%sc", (x++ > 0) ? "," : "");
10306 		if(temp_contact->notify_on_service_recovery == TRUE)
10307 			fprintf(fp, "%sr", (x++ > 0) ? "," : "");
10308 		if(temp_contact->notify_on_service_flapping == TRUE)
10309 			fprintf(fp, "%sf", (x++ > 0) ? "," : "");
10310 		if(temp_contact->notify_on_service_downtime == TRUE)
10311 			fprintf(fp, "%ss", (x++ > 0) ? "," : "");
10312 		if(x == 0)
10313 			fprintf(fp, "n");
10314 		fprintf(fp, "\n");
10315 		fprintf(fp, "\thost_notification_options\t");
10316 		x = 0;
10317 		if(temp_contact->notify_on_host_down == TRUE)
10318 			fprintf(fp, "%sd", (x++ > 0) ? "," : "");
10319 		if(temp_contact->notify_on_host_unreachable == TRUE)
10320 			fprintf(fp, "%su", (x++ > 0) ? "," : "");
10321 		if(temp_contact->notify_on_host_recovery == TRUE)
10322 			fprintf(fp, "%sr", (x++ > 0) ? "," : "");
10323 		if(temp_contact->notify_on_host_flapping == TRUE)
10324 			fprintf(fp, "%sf", (x++ > 0) ? "," : "");
10325 		if(temp_contact->notify_on_host_downtime == TRUE)
10326 			fprintf(fp, "%ss", (x++ > 0) ? "," : "");
10327 		if(x == 0)
10328 			fprintf(fp, "n");
10329 		fprintf(fp, "\n");
10330 		if(temp_contact->service_notification_commands)
10331 			fprintf(fp, "\tservice_notification_commands\t%s\n", temp_contact->service_notification_commands);
10332 		if(temp_contact->host_notification_commands)
10333 			fprintf(fp, "\thost_notification_commands\t%s\n", temp_contact->host_notification_commands);
10334 		if(temp_contact->email)
10335 			fprintf(fp, "\temail\t%s\n", temp_contact->email);
10336 		if(temp_contact->pager)
10337 			fprintf(fp, "\tpager\t%s\n", temp_contact->pager);
10338 		for(x = 0; x < MAX_XODTEMPLATE_CONTACT_ADDRESSES; x++) {
10339 			if(temp_contact->address[x])
10340 				fprintf(fp, "\taddress%d\t%s\n", x + 1, temp_contact->address[x]);
10341 			}
10342 		fprintf(fp, "\thost_notifications_enabled\t%d\n", temp_contact->host_notifications_enabled);
10343 		fprintf(fp, "\tservice_notifications_enabled\t%d\n", temp_contact->service_notifications_enabled);
10344 		fprintf(fp, "\tcan_submit_commands\t%d\n", temp_contact->can_submit_commands);
10345 		fprintf(fp, "\tretain_status_information\t%d\n", temp_contact->retain_status_information);
10346 		fprintf(fp, "\tretain_nonstatus_information\t%d\n", temp_contact->retain_nonstatus_information);
10347 
10348 		/* custom variables */
10349 		for(temp_customvariablesmember = temp_contact->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) {
10350 			if(temp_customvariablesmember->variable_name)
10351 				fprintf(fp, "\t_%s\t%s\n", temp_customvariablesmember->variable_name, (temp_customvariablesmember->variable_value == NULL) ? XODTEMPLATE_NULL : temp_customvariablesmember->variable_value);
10352 			}
10353 
10354 
10355 		fprintf(fp, "\t}\n\n");
10356 		}
10357 
10358 	/* cache hosts */
10359 	/*for(temp_host=xodtemplate_host_list;temp_host!=NULL;temp_host=temp_host->next){*/
10360 	ptr = NULL;
10361 	for(temp_host = (xodtemplate_host *)skiplist_get_first(xobject_skiplists[X_HOST_SKIPLIST], &ptr); temp_host != NULL; temp_host = (xodtemplate_host *)skiplist_get_next(&ptr)) {
10362 		if(temp_host->register_object == FALSE)
10363 			continue;
10364 		fprintf(fp, "define host {\n");
10365 		if(temp_host->host_name)
10366 			fprintf(fp, "\thost_name\t%s\n", temp_host->host_name);
10367 		if(temp_host->display_name)
10368 			fprintf(fp, "\tdisplay_name\t%s\n", temp_host->display_name);
10369 		if(temp_host->alias)
10370 			fprintf(fp, "\talias\t%s\n", temp_host->alias);
10371 		if(temp_host->address)
10372 			fprintf(fp, "\taddress\t%s\n", temp_host->address);
10373 		if(temp_host->parents)
10374 			fprintf(fp, "\tparents\t%s\n", temp_host->parents);
10375 		if(temp_host->check_period)
10376 			fprintf(fp, "\tcheck_period\t%s\n", temp_host->check_period);
10377 		if(temp_host->check_command)
10378 			fprintf(fp, "\tcheck_command\t%s\n", temp_host->check_command);
10379 		if(temp_host->event_handler)
10380 			fprintf(fp, "\tevent_handler\t%s\n", temp_host->event_handler);
10381 		if(temp_host->contacts)
10382 			fprintf(fp, "\tcontacts\t%s\n", temp_host->contacts);
10383 		if(temp_host->contact_groups)
10384 			fprintf(fp, "\tcontact_groups\t%s\n", temp_host->contact_groups);
10385 		if(temp_host->notification_period)
10386 			fprintf(fp, "\tnotification_period\t%s\n", temp_host->notification_period);
10387 		if(temp_host->failure_prediction_options)
10388 			fprintf(fp, "\tfailure_prediction_options\t%s\n", temp_host->failure_prediction_options);
10389 		fprintf(fp, "\tinitial_state\t");
10390 		if(temp_host->initial_state == HOST_DOWN)
10391 			fprintf(fp, "d\n");
10392 		else if(temp_host->initial_state == HOST_UNREACHABLE)
10393 			fprintf(fp, "u\n");
10394 		else
10395 			fprintf(fp, "o\n");
10396 		fprintf(fp, "\tcheck_interval\t%f\n", temp_host->check_interval);
10397 		fprintf(fp, "\tretry_interval\t%f\n", temp_host->retry_interval);
10398 		fprintf(fp, "\tmax_check_attempts\t%d\n", temp_host->max_check_attempts);
10399 		fprintf(fp, "\tactive_checks_enabled\t%d\n", temp_host->active_checks_enabled);
10400 		fprintf(fp, "\tpassive_checks_enabled\t%d\n", temp_host->passive_checks_enabled);
10401 		fprintf(fp, "\tobsess_over_host\t%d\n", temp_host->obsess_over_host);
10402 		fprintf(fp, "\tevent_handler_enabled\t%d\n", temp_host->event_handler_enabled);
10403 		fprintf(fp, "\tlow_flap_threshold\t%f\n", temp_host->low_flap_threshold);
10404 		fprintf(fp, "\thigh_flap_threshold\t%f\n", temp_host->high_flap_threshold);
10405 		fprintf(fp, "\tflap_detection_enabled\t%d\n", temp_host->flap_detection_enabled);
10406 		fprintf(fp, "\tflap_detection_options\t");
10407 		x = 0;
10408 		if(temp_host->flap_detection_on_up == TRUE)
10409 			fprintf(fp, "%so", (x++ > 0) ? "," : "");
10410 		if(temp_host->flap_detection_on_down == TRUE)
10411 			fprintf(fp, "%sd", (x++ > 0) ? "," : "");
10412 		if(temp_host->flap_detection_on_unreachable == TRUE)
10413 			fprintf(fp, "%su", (x++ > 0) ? "," : "");
10414 		if(x == 0)
10415 			fprintf(fp, "n");
10416 		fprintf(fp, "\n");
10417 		fprintf(fp, "\tfreshness_threshold\t%d\n", temp_host->freshness_threshold);
10418 		fprintf(fp, "\tcheck_freshness\t%d\n", temp_host->check_freshness);
10419 		fprintf(fp, "\tnotification_options\t");
10420 		x = 0;
10421 		if(temp_host->notify_on_down == TRUE)
10422 			fprintf(fp, "%sd", (x++ > 0) ? "," : "");
10423 		if(temp_host->notify_on_unreachable == TRUE)
10424 			fprintf(fp, "%su", (x++ > 0) ? "," : "");
10425 		if(temp_host->notify_on_recovery == TRUE)
10426 			fprintf(fp, "%sr", (x++ > 0) ? "," : "");
10427 		if(temp_host->notify_on_flapping == TRUE)
10428 			fprintf(fp, "%sf", (x++ > 0) ? "," : "");
10429 		if(temp_host->notify_on_downtime == TRUE)
10430 			fprintf(fp, "%ss", (x++ > 0) ? "," : "");
10431 		if(x == 0)
10432 			fprintf(fp, "n");
10433 		fprintf(fp, "\n");
10434 		fprintf(fp, "\tnotifications_enabled\t%d\n", temp_host->notifications_enabled);
10435 		fprintf(fp, "\tnotification_interval\t%f\n", temp_host->notification_interval);
10436 		fprintf(fp, "\tfirst_notification_delay\t%f\n", temp_host->first_notification_delay);
10437 		fprintf(fp, "\tstalking_options\t");
10438 		x = 0;
10439 		if(temp_host->stalk_on_up == TRUE)
10440 			fprintf(fp, "%so", (x++ > 0) ? "," : "");
10441 		if(temp_host->stalk_on_down == TRUE)
10442 			fprintf(fp, "%sd", (x++ > 0) ? "," : "");
10443 		if(temp_host->stalk_on_unreachable == TRUE)
10444 			fprintf(fp, "%su", (x++ > 0) ? "," : "");
10445 		if(x == 0)
10446 			fprintf(fp, "n");
10447 		fprintf(fp, "\n");
10448 		fprintf(fp, "\tprocess_perf_data\t%d\n", temp_host->process_perf_data);
10449 		fprintf(fp, "\tfailure_prediction_enabled\t%d\n", temp_host->failure_prediction_enabled);
10450 		if(temp_host->icon_image)
10451 			fprintf(fp, "\ticon_image\t%s\n", temp_host->icon_image);
10452 		if(temp_host->icon_image_alt)
10453 			fprintf(fp, "\ticon_image_alt\t%s\n", temp_host->icon_image_alt);
10454 		if(temp_host->vrml_image)
10455 			fprintf(fp, "\tvrml_image\t%s\n", temp_host->vrml_image);
10456 		if(temp_host->statusmap_image)
10457 			fprintf(fp, "\tstatusmap_image\t%s\n", temp_host->statusmap_image);
10458 		if(temp_host->have_2d_coords == TRUE)
10459 			fprintf(fp, "\t2d_coords\t%d,%d\n", temp_host->x_2d, temp_host->y_2d);
10460 		if(temp_host->have_3d_coords == TRUE)
10461 			fprintf(fp, "\t3d_coords\t%f,%f,%f\n", temp_host->x_3d, temp_host->y_3d, temp_host->z_3d);
10462 		if(temp_host->notes)
10463 			fprintf(fp, "\tnotes\t%s\n", temp_host->notes);
10464 		if(temp_host->notes_url)
10465 			fprintf(fp, "\tnotes_url\t%s\n", temp_host->notes_url);
10466 		if(temp_host->action_url)
10467 			fprintf(fp, "\taction_url\t%s\n", temp_host->action_url);
10468 		fprintf(fp, "\tretain_status_information\t%d\n", temp_host->retain_status_information);
10469 		fprintf(fp, "\tretain_nonstatus_information\t%d\n", temp_host->retain_nonstatus_information);
10470 
10471 		/* custom variables */
10472 		for(temp_customvariablesmember = temp_host->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) {
10473 			if(temp_customvariablesmember->variable_name)
10474 				fprintf(fp, "\t_%s\t%s\n", temp_customvariablesmember->variable_name, (temp_customvariablesmember->variable_value == NULL) ? XODTEMPLATE_NULL : temp_customvariablesmember->variable_value);
10475 			}
10476 
10477 
10478 		fprintf(fp, "\t}\n\n");
10479 		}
10480 
10481 	/* cache services */
10482 	/*for(temp_service=xodtemplate_service_list;temp_service!=NULL;temp_service=temp_service->next){*/
10483 	ptr = NULL;
10484 	for(temp_service = (xodtemplate_service *)skiplist_get_first(xobject_skiplists[X_SERVICE_SKIPLIST], &ptr); temp_service != NULL; temp_service = (xodtemplate_service *)skiplist_get_next(&ptr)) {
10485 		if(temp_service->register_object == FALSE)
10486 			continue;
10487 		fprintf(fp, "define service {\n");
10488 		if(temp_service->host_name)
10489 			fprintf(fp, "\thost_name\t%s\n", temp_service->host_name);
10490 		if(temp_service->service_description)
10491 			fprintf(fp, "\tservice_description\t%s\n", temp_service->service_description);
10492 		if(temp_service->display_name)
10493 			fprintf(fp, "\tdisplay_name\t%s\n", temp_service->display_name);
10494 		if(temp_service->check_period)
10495 			fprintf(fp, "\tcheck_period\t%s\n", temp_service->check_period);
10496 		if(temp_service->check_command)
10497 			fprintf(fp, "\tcheck_command\t%s\n", temp_service->check_command);
10498 		if(temp_service->event_handler)
10499 			fprintf(fp, "\tevent_handler\t%s\n", temp_service->event_handler);
10500 		if(temp_service->contacts)
10501 			fprintf(fp, "\tcontacts\t%s\n", temp_service->contacts);
10502 		if(temp_service->contact_groups)
10503 			fprintf(fp, "\tcontact_groups\t%s\n", temp_service->contact_groups);
10504 		if(temp_service->notification_period)
10505 			fprintf(fp, "\tnotification_period\t%s\n", temp_service->notification_period);
10506 		if(temp_service->failure_prediction_options)
10507 			fprintf(fp, "\tfailure_prediction_options\t%s\n", temp_service->failure_prediction_options);
10508 		fprintf(fp, "\tinitial_state\t");
10509 		if(temp_service->initial_state == STATE_WARNING)
10510 			fprintf(fp, "w\n");
10511 		else if(temp_service->initial_state == STATE_UNKNOWN)
10512 			fprintf(fp, "u\n");
10513 		else if(temp_service->initial_state == STATE_CRITICAL)
10514 			fprintf(fp, "c\n");
10515 		else
10516 			fprintf(fp, "o\n");
10517 		fprintf(fp, "\tcheck_interval\t%f\n", temp_service->check_interval);
10518 		fprintf(fp, "\tretry_interval\t%f\n", temp_service->retry_interval);
10519 		fprintf(fp, "\tmax_check_attempts\t%d\n", temp_service->max_check_attempts);
10520 		fprintf(fp, "\tis_volatile\t%d\n", temp_service->is_volatile);
10521 		fprintf(fp, "\tparallelize_check\t%d\n", temp_service->parallelize_check);
10522 		fprintf(fp, "\tactive_checks_enabled\t%d\n", temp_service->active_checks_enabled);
10523 		fprintf(fp, "\tpassive_checks_enabled\t%d\n", temp_service->passive_checks_enabled);
10524 		fprintf(fp, "\tobsess_over_service\t%d\n", temp_service->obsess_over_service);
10525 		fprintf(fp, "\tevent_handler_enabled\t%d\n", temp_service->event_handler_enabled);
10526 		fprintf(fp, "\tlow_flap_threshold\t%f\n", temp_service->low_flap_threshold);
10527 		fprintf(fp, "\thigh_flap_threshold\t%f\n", temp_service->high_flap_threshold);
10528 		fprintf(fp, "\tflap_detection_enabled\t%d\n", temp_service->flap_detection_enabled);
10529 		fprintf(fp, "\tflap_detection_options\t");
10530 		x = 0;
10531 		if(temp_service->flap_detection_on_ok == TRUE)
10532 			fprintf(fp, "%so", (x++ > 0) ? "," : "");
10533 		if(temp_service->flap_detection_on_warning == TRUE)
10534 			fprintf(fp, "%sw", (x++ > 0) ? "," : "");
10535 		if(temp_service->flap_detection_on_unknown == TRUE)
10536 			fprintf(fp, "%su", (x++ > 0) ? "," : "");
10537 		if(temp_service->flap_detection_on_critical == TRUE)
10538 			fprintf(fp, "%sc", (x++ > 0) ? "," : "");
10539 		if(x == 0)
10540 			fprintf(fp, "n");
10541 		fprintf(fp, "\n");
10542 		fprintf(fp, "\tfreshness_threshold\t%d\n", temp_service->freshness_threshold);
10543 		fprintf(fp, "\tcheck_freshness\t%d\n", temp_service->check_freshness);
10544 		fprintf(fp, "\tnotification_options\t");
10545 		x = 0;
10546 		if(temp_service->notify_on_unknown == TRUE)
10547 			fprintf(fp, "%su", (x++ > 0) ? "," : "");
10548 		if(temp_service->notify_on_warning == TRUE)
10549 			fprintf(fp, "%sw", (x++ > 0) ? "," : "");
10550 		if(temp_service->notify_on_critical == TRUE)
10551 			fprintf(fp, "%sc", (x++ > 0) ? "," : "");
10552 		if(temp_service->notify_on_recovery == TRUE)
10553 			fprintf(fp, "%sr", (x++ > 0) ? "," : "");
10554 		if(temp_service->notify_on_flapping == TRUE)
10555 			fprintf(fp, "%sf", (x++ > 0) ? "," : "");
10556 		if(temp_service->notify_on_downtime == TRUE)
10557 			fprintf(fp, "%ss", (x++ > 0) ? "," : "");
10558 		if(x == 0)
10559 			fprintf(fp, "n");
10560 		fprintf(fp, "\n");
10561 		fprintf(fp, "\tnotifications_enabled\t%d\n", temp_service->notifications_enabled);
10562 		fprintf(fp, "\tnotification_interval\t%f\n", temp_service->notification_interval);
10563 		fprintf(fp, "\tfirst_notification_delay\t%f\n", temp_service->first_notification_delay);
10564 		fprintf(fp, "\tstalking_options\t");
10565 		x = 0;
10566 		if(temp_service->stalk_on_ok == TRUE)
10567 			fprintf(fp, "%so", (x++ > 0) ? "," : "");
10568 		if(temp_service->stalk_on_unknown == TRUE)
10569 			fprintf(fp, "%su", (x++ > 0) ? "," : "");
10570 		if(temp_service->stalk_on_warning == TRUE)
10571 			fprintf(fp, "%sw", (x++ > 0) ? "," : "");
10572 		if(temp_service->stalk_on_critical == TRUE)
10573 			fprintf(fp, "%sc", (x++ > 0) ? "," : "");
10574 		if(x == 0)
10575 			fprintf(fp, "n");
10576 		fprintf(fp, "\n");
10577 		fprintf(fp, "\tprocess_perf_data\t%d\n", temp_service->process_perf_data);
10578 		fprintf(fp, "\tfailure_prediction_enabled\t%d\n", temp_service->failure_prediction_enabled);
10579 		if(temp_service->icon_image)
10580 			fprintf(fp, "\ticon_image\t%s\n", temp_service->icon_image);
10581 		if(temp_service->icon_image_alt)
10582 			fprintf(fp, "\ticon_image_alt\t%s\n", temp_service->icon_image_alt);
10583 		if(temp_service->notes)
10584 			fprintf(fp, "\tnotes\t%s\n", temp_service->notes);
10585 		if(temp_service->notes_url)
10586 			fprintf(fp, "\tnotes_url\t%s\n", temp_service->notes_url);
10587 		if(temp_service->action_url)
10588 			fprintf(fp, "\taction_url\t%s\n", temp_service->action_url);
10589 		fprintf(fp, "\tretain_status_information\t%d\n", temp_service->retain_status_information);
10590 		fprintf(fp, "\tretain_nonstatus_information\t%d\n", temp_service->retain_nonstatus_information);
10591 
10592 		/* custom variables */
10593 		for(temp_customvariablesmember = temp_service->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) {
10594 			if(temp_customvariablesmember->variable_name)
10595 				fprintf(fp, "\t_%s\t%s\n", temp_customvariablesmember->variable_name, (temp_customvariablesmember->variable_value == NULL) ? XODTEMPLATE_NULL : temp_customvariablesmember->variable_value);
10596 			}
10597 
10598 		fprintf(fp, "\t}\n\n");
10599 		}
10600 
10601 	/* cache service dependencies */
10602 	/*for(temp_servicedependency=xodtemplate_servicedependency_list;temp_servicedependency!=NULL;temp_servicedependency=temp_servicedependency->next){*/
10603 	ptr = NULL;
10604 	for(temp_servicedependency = (xodtemplate_servicedependency *)skiplist_get_first(xobject_skiplists[X_SERVICEDEPENDENCY_SKIPLIST], &ptr); temp_servicedependency != NULL; temp_servicedependency = (xodtemplate_servicedependency *)skiplist_get_next(&ptr)) {
10605 		if(temp_servicedependency->register_object == FALSE)
10606 			continue;
10607 		fprintf(fp, "define servicedependency {\n");
10608 		if(temp_servicedependency->host_name)
10609 			fprintf(fp, "\thost_name\t%s\n", temp_servicedependency->host_name);
10610 		if(temp_servicedependency->service_description)
10611 			fprintf(fp, "\tservice_description\t%s\n", temp_servicedependency->service_description);
10612 		if(temp_servicedependency->dependent_host_name)
10613 			fprintf(fp, "\tdependent_host_name\t%s\n", temp_servicedependency->dependent_host_name);
10614 		if(temp_servicedependency->dependent_service_description)
10615 			fprintf(fp, "\tdependent_service_description\t%s\n", temp_servicedependency->dependent_service_description);
10616 		if(temp_servicedependency->dependency_period)
10617 			fprintf(fp, "\tdependency_period\t%s\n", temp_servicedependency->dependency_period);
10618 		fprintf(fp, "\tinherits_parent\t%d\n", temp_servicedependency->inherits_parent);
10619 		if(temp_servicedependency->have_notification_dependency_options == TRUE) {
10620 			fprintf(fp, "\tnotification_failure_options\t");
10621 			x = 0;
10622 			if(temp_servicedependency->fail_notify_on_ok == TRUE)
10623 				fprintf(fp, "%so", (x++ > 0) ? "," : "");
10624 			if(temp_servicedependency->fail_notify_on_unknown == TRUE)
10625 				fprintf(fp, "%su", (x++ > 0) ? "," : "");
10626 			if(temp_servicedependency->fail_notify_on_warning == TRUE)
10627 				fprintf(fp, "%sw", (x++ > 0) ? "," : "");
10628 			if(temp_servicedependency->fail_notify_on_critical == TRUE)
10629 				fprintf(fp, "%sc", (x++ > 0) ? "," : "");
10630 			if(temp_servicedependency->fail_notify_on_pending == TRUE)
10631 				fprintf(fp, "%sp", (x++ > 0) ? "," : "");
10632 			if(x == 0)
10633 				fprintf(fp, "n");
10634 			fprintf(fp, "\n");
10635 			}
10636 		if(temp_servicedependency->have_execution_dependency_options == TRUE) {
10637 			fprintf(fp, "\texecution_failure_options\t");
10638 			x = 0;
10639 			if(temp_servicedependency->fail_execute_on_ok == TRUE)
10640 				fprintf(fp, "%so", (x++ > 0) ? "," : "");
10641 			if(temp_servicedependency->fail_execute_on_unknown == TRUE)
10642 				fprintf(fp, "%su", (x++ > 0) ? "," : "");
10643 			if(temp_servicedependency->fail_execute_on_warning == TRUE)
10644 				fprintf(fp, "%sw", (x++ > 0) ? "," : "");
10645 			if(temp_servicedependency->fail_execute_on_critical == TRUE)
10646 				fprintf(fp, "%sc", (x++ > 0) ? "," : "");
10647 			if(temp_servicedependency->fail_execute_on_pending == TRUE)
10648 				fprintf(fp, "%sp", (x++ > 0) ? "," : "");
10649 			if(x == 0)
10650 				fprintf(fp, "n");
10651 			fprintf(fp, "\n");
10652 			}
10653 		fprintf(fp, "\t}\n\n");
10654 		}
10655 
10656 	/* cache service escalations */
10657 	/*for(temp_serviceescalation=xodtemplate_serviceescalation_list;temp_serviceescalation!=NULL;temp_serviceescalation=temp_serviceescalation->next){*/
10658 	ptr = NULL;
10659 	for(temp_serviceescalation = (xodtemplate_serviceescalation *)skiplist_get_first(xobject_skiplists[X_SERVICEESCALATION_SKIPLIST], &ptr); temp_serviceescalation != NULL; temp_serviceescalation = (xodtemplate_serviceescalation *)skiplist_get_next(&ptr)) {
10660 		if(temp_serviceescalation->register_object == FALSE)
10661 			continue;
10662 		fprintf(fp, "define serviceescalation {\n");
10663 		if(temp_serviceescalation->host_name)
10664 			fprintf(fp, "\thost_name\t%s\n", temp_serviceescalation->host_name);
10665 		if(temp_serviceescalation->service_description)
10666 			fprintf(fp, "\tservice_description\t%s\n", temp_serviceescalation->service_description);
10667 		fprintf(fp, "\tfirst_notification\t%d\n", temp_serviceescalation->first_notification);
10668 		fprintf(fp, "\tlast_notification\t%d\n", temp_serviceescalation->last_notification);
10669 		fprintf(fp, "\tnotification_interval\t%f\n", temp_serviceescalation->notification_interval);
10670 		if(temp_serviceescalation->escalation_period)
10671 			fprintf(fp, "\tescalation_period\t%s\n", temp_serviceescalation->escalation_period);
10672 		if(temp_serviceescalation->have_escalation_options == TRUE) {
10673 			fprintf(fp, "\tescalation_options\t");
10674 			x = 0;
10675 			if(temp_serviceescalation->escalate_on_warning == TRUE)
10676 				fprintf(fp, "%sw", (x++ > 0) ? "," : "");
10677 			if(temp_serviceescalation->escalate_on_unknown == TRUE)
10678 				fprintf(fp, "%su", (x++ > 0) ? "," : "");
10679 			if(temp_serviceescalation->escalate_on_critical == TRUE)
10680 				fprintf(fp, "%sc", (x++ > 0) ? "," : "");
10681 			if(temp_serviceescalation->escalate_on_recovery == TRUE)
10682 				fprintf(fp, "%sr", (x++ > 0) ? "," : "");
10683 			if(x == 0)
10684 				fprintf(fp, "n");
10685 			fprintf(fp, "\n");
10686 			}
10687 		if(temp_serviceescalation->contacts)
10688 			fprintf(fp, "\tcontacts\t%s\n", temp_serviceescalation->contacts);
10689 		if(temp_serviceescalation->contact_groups)
10690 			fprintf(fp, "\tcontact_groups\t%s\n", temp_serviceescalation->contact_groups);
10691 		fprintf(fp, "\t}\n\n");
10692 		}
10693 
10694 	/* cache host dependencies */
10695 	/*for(temp_hostdependency=xodtemplate_hostdependency_list;temp_hostdependency!=NULL;temp_hostdependency=temp_hostdependency->next){*/
10696 	ptr = NULL;
10697 	for(temp_hostdependency = (xodtemplate_hostdependency *)skiplist_get_first(xobject_skiplists[X_HOSTDEPENDENCY_SKIPLIST], &ptr); temp_hostdependency != NULL; temp_hostdependency = (xodtemplate_hostdependency *)skiplist_get_next(&ptr)) {
10698 		if(temp_hostdependency->register_object == FALSE)
10699 			continue;
10700 		fprintf(fp, "define hostdependency {\n");
10701 		if(temp_hostdependency->host_name)
10702 			fprintf(fp, "\thost_name\t%s\n", temp_hostdependency->host_name);
10703 		if(temp_hostdependency->dependent_host_name)
10704 			fprintf(fp, "\tdependent_host_name\t%s\n", temp_hostdependency->dependent_host_name);
10705 		if(temp_hostdependency->dependency_period)
10706 			fprintf(fp, "\tdependency_period\t%s\n", temp_hostdependency->dependency_period);
10707 		fprintf(fp, "\tinherits_parent\t%d\n", temp_hostdependency->inherits_parent);
10708 		if(temp_hostdependency->have_notification_dependency_options == TRUE) {
10709 			fprintf(fp, "\tnotification_failure_options\t");
10710 			x = 0;
10711 			if(temp_hostdependency->fail_notify_on_up == TRUE)
10712 				fprintf(fp, "%so", (x++ > 0) ? "," : "");
10713 			if(temp_hostdependency->fail_notify_on_down == TRUE)
10714 				fprintf(fp, "%sd", (x++ > 0) ? "," : "");
10715 			if(temp_hostdependency->fail_notify_on_unreachable == TRUE)
10716 				fprintf(fp, "%su", (x++ > 0) ? "," : "");
10717 			if(temp_hostdependency->fail_notify_on_pending == TRUE)
10718 				fprintf(fp, "%sp", (x++ > 0) ? "," : "");
10719 			if(x == 0)
10720 				fprintf(fp, "n");
10721 			fprintf(fp, "\n");
10722 			}
10723 		if(temp_hostdependency->have_execution_dependency_options == TRUE) {
10724 			fprintf(fp, "\texecution_failure_options\t");
10725 			x = 0;
10726 			if(temp_hostdependency->fail_execute_on_up == TRUE)
10727 				fprintf(fp, "%so", (x++ > 0) ? "," : "");
10728 			if(temp_hostdependency->fail_execute_on_down == TRUE)
10729 				fprintf(fp, "%sd", (x++ > 0) ? "," : "");
10730 			if(temp_hostdependency->fail_execute_on_unreachable == TRUE)
10731 				fprintf(fp, "%su", (x++ > 0) ? "," : "");
10732 			if(temp_hostdependency->fail_execute_on_pending == TRUE)
10733 				fprintf(fp, "%sp", (x++ > 0) ? "," : "");
10734 			if(x == 0)
10735 				fprintf(fp, "n");
10736 			fprintf(fp, "\n");
10737 			}
10738 		fprintf(fp, "\t}\n\n");
10739 		}
10740 
10741 	/* cache host escalations */
10742 	/*for(temp_hostescalation=xodtemplate_hostescalation_list;temp_hostescalation!=NULL;temp_hostescalation=temp_hostescalation->next){*/
10743 	ptr = NULL;
10744 	for(temp_hostescalation = (xodtemplate_hostescalation *)skiplist_get_first(xobject_skiplists[X_HOSTESCALATION_SKIPLIST], &ptr); temp_hostescalation != NULL; temp_hostescalation = (xodtemplate_hostescalation *)skiplist_get_next(&ptr)) {
10745 		if(temp_hostescalation->register_object == FALSE)
10746 			continue;
10747 		fprintf(fp, "define hostescalation {\n");
10748 		if(temp_hostescalation->host_name)
10749 			fprintf(fp, "\thost_name\t%s\n", temp_hostescalation->host_name);
10750 		fprintf(fp, "\tfirst_notification\t%d\n", temp_hostescalation->first_notification);
10751 		fprintf(fp, "\tlast_notification\t%d\n", temp_hostescalation->last_notification);
10752 		fprintf(fp, "\tnotification_interval\t%f\n", temp_hostescalation->notification_interval);
10753 		if(temp_hostescalation->escalation_period)
10754 			fprintf(fp, "\tescalation_period\t%s\n", temp_hostescalation->escalation_period);
10755 		if(temp_hostescalation->have_escalation_options == TRUE) {
10756 			fprintf(fp, "\tescalation_options\t");
10757 			x = 0;
10758 			if(temp_hostescalation->escalate_on_down == TRUE)
10759 				fprintf(fp, "%sd", (x++ > 0) ? "," : "");
10760 			if(temp_hostescalation->escalate_on_unreachable == TRUE)
10761 				fprintf(fp, "%su", (x++ > 0) ? "," : "");
10762 			if(temp_hostescalation->escalate_on_recovery == TRUE)
10763 				fprintf(fp, "%sr", (x++ > 0) ? "," : "");
10764 			if(x == 0)
10765 				fprintf(fp, "n");
10766 			fprintf(fp, "\n");
10767 			}
10768 		if(temp_hostescalation->contacts)
10769 			fprintf(fp, "\tcontacts\t%s\n", temp_hostescalation->contacts);
10770 		if(temp_hostescalation->contact_groups)
10771 			fprintf(fp, "\tcontact_groups\t%s\n", temp_hostescalation->contact_groups);
10772 		fprintf(fp, "\t}\n\n");
10773 		}
10774 
10775 	fclose(fp);
10776 
10777 	return OK;
10778 	}
10779 
10780 #endif
10781 
10782 /******************************************************************/
10783 /******************** SKIPLIST FUNCTIONS **************************/
10784 /******************************************************************/
10785 
xodtemplate_init_xobject_skiplists(void)10786 int xodtemplate_init_xobject_skiplists(void) {
10787 	int x = 0;
10788 
10789 	for(x = 0; x < NUM_XOBJECT_SKIPLISTS; x++) {
10790 		xobject_template_skiplists[x] = NULL;
10791 		xobject_skiplists[x] = NULL;
10792 		}
10793 
10794 	xobject_template_skiplists[X_HOST_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_host_template);
10795 	xobject_template_skiplists[X_SERVICE_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_service_template);
10796 	xobject_template_skiplists[X_COMMAND_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_command_template);
10797 	xobject_template_skiplists[X_TIMEPERIOD_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_timeperiod_template);
10798 	xobject_template_skiplists[X_CONTACT_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_contact_template);
10799 	xobject_template_skiplists[X_CONTACTGROUP_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_contactgroup_template);
10800 	xobject_template_skiplists[X_HOSTGROUP_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_hostgroup_template);
10801 	xobject_template_skiplists[X_SERVICEGROUP_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_servicegroup_template);
10802 	xobject_template_skiplists[X_HOSTDEPENDENCY_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_hostdependency_template);
10803 	xobject_template_skiplists[X_SERVICEDEPENDENCY_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_servicedependency_template);
10804 	xobject_template_skiplists[X_HOSTESCALATION_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_hostescalation_template);
10805 	xobject_template_skiplists[X_SERVICEESCALATION_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_serviceescalation_template);
10806 	xobject_template_skiplists[X_HOSTEXTINFO_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_hostextinfo_template);
10807 	xobject_template_skiplists[X_SERVICEEXTINFO_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_serviceextinfo_template);
10808 
10809 	xobject_skiplists[X_HOST_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_host);
10810 	xobject_skiplists[X_SERVICE_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_service);
10811 	xobject_skiplists[X_COMMAND_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_command);
10812 	xobject_skiplists[X_TIMEPERIOD_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_timeperiod);
10813 	xobject_skiplists[X_CONTACT_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_contact);
10814 	xobject_skiplists[X_CONTACTGROUP_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_contactgroup);
10815 	xobject_skiplists[X_HOSTGROUP_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_hostgroup);
10816 	xobject_skiplists[X_SERVICEGROUP_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_servicegroup);
10817 	/* allow dups in the following lists... */
10818 	xobject_skiplists[X_HOSTDEPENDENCY_SKIPLIST] = skiplist_new(16, 0.5, TRUE, FALSE, xodtemplate_skiplist_compare_hostdependency);
10819 	xobject_skiplists[X_SERVICEDEPENDENCY_SKIPLIST] = skiplist_new(16, 0.5, TRUE, FALSE, xodtemplate_skiplist_compare_servicedependency);
10820 	xobject_skiplists[X_HOSTESCALATION_SKIPLIST] = skiplist_new(16, 0.5, TRUE, FALSE, xodtemplate_skiplist_compare_hostescalation);
10821 	xobject_skiplists[X_SERVICEESCALATION_SKIPLIST] = skiplist_new(16, 0.5, TRUE, FALSE, xodtemplate_skiplist_compare_serviceescalation);
10822 	/* host and service extinfo entries don't need to be added to a list... */
10823 
10824 	return OK;
10825 	}
10826 
10827 
10828 
xodtemplate_free_xobject_skiplists(void)10829 int xodtemplate_free_xobject_skiplists(void) {
10830 	int x = 0;
10831 
10832 	for(x = 0; x < NUM_XOBJECT_SKIPLISTS; x++) {
10833 		skiplist_free(&xobject_template_skiplists[x]);
10834 		skiplist_free(&xobject_skiplists[x]);
10835 		}
10836 
10837 	return OK;
10838 	}
10839 
10840 
xodtemplate_skiplist_compare_text(const char * val1a,const char * val1b,const char * val2a,const char * val2b)10841 int xodtemplate_skiplist_compare_text(const char *val1a, const char *val1b, const char *val2a, const char *val2b) {
10842 	int result = 0;
10843 
10844 	/* check first name */
10845 	if(val1a == NULL && val2a == NULL)
10846 		result = 0;
10847 	else if(val1a == NULL)
10848 		result = 1;
10849 	else if(val2a == NULL)
10850 		result = -1;
10851 	else
10852 		result = strcmp(val1a, val2a);
10853 
10854 	/* check second name if necessary */
10855 	if(result == 0) {
10856 		if(val1b == NULL && val2b == NULL)
10857 			result = 0;
10858 		else if(val1b == NULL)
10859 			result = 1;
10860 		else if(val2b == NULL)
10861 			result = -1;
10862 		else
10863 			result = strcmp(val1b, val2b);
10864 		}
10865 
10866 	return result;
10867 	}
10868 
10869 
10870 
xodtemplate_skiplist_compare_host_template(void * a,void * b)10871 int xodtemplate_skiplist_compare_host_template(void *a, void *b) {
10872 	xodtemplate_host *oa = NULL;
10873 	xodtemplate_host *ob = NULL;
10874 
10875 	oa = (xodtemplate_host *)a;
10876 	ob = (xodtemplate_host *)b;
10877 
10878 	if(oa == NULL && ob == NULL)
10879 		return 0;
10880 	if(oa == NULL)
10881 		return 1;
10882 	if(ob == NULL)
10883 		return -1;
10884 
10885 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
10886 	}
10887 
10888 
10889 
xodtemplate_skiplist_compare_host(void * a,void * b)10890 int xodtemplate_skiplist_compare_host(void *a, void *b) {
10891 	xodtemplate_host *oa = NULL;
10892 	xodtemplate_host *ob = NULL;
10893 
10894 	oa = (xodtemplate_host *)a;
10895 	ob = (xodtemplate_host *)b;
10896 
10897 	if(oa == NULL && ob == NULL)
10898 		return 0;
10899 	if(oa == NULL)
10900 		return 1;
10901 	if(ob == NULL)
10902 		return -1;
10903 
10904 	return skiplist_compare_text(oa->host_name, NULL, ob->host_name, NULL);
10905 	}
10906 
10907 
10908 
xodtemplate_skiplist_compare_service_template(void * a,void * b)10909 int xodtemplate_skiplist_compare_service_template(void *a, void *b) {
10910 	xodtemplate_service *oa = NULL;
10911 	xodtemplate_service *ob = NULL;
10912 
10913 	oa = (xodtemplate_service *)a;
10914 	ob = (xodtemplate_service *)b;
10915 
10916 	if(oa == NULL && ob == NULL)
10917 		return 0;
10918 	if(oa == NULL)
10919 		return 1;
10920 	if(ob == NULL)
10921 		return -1;
10922 
10923 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
10924 	}
10925 
10926 
10927 
xodtemplate_skiplist_compare_service(void * a,void * b)10928 int xodtemplate_skiplist_compare_service(void *a, void *b) {
10929 	xodtemplate_service *oa = NULL;
10930 	xodtemplate_service *ob = NULL;
10931 
10932 	oa = (xodtemplate_service *)a;
10933 	ob = (xodtemplate_service *)b;
10934 
10935 	if(oa == NULL && ob == NULL)
10936 		return 0;
10937 	if(oa == NULL)
10938 		return 1;
10939 	if(ob == NULL)
10940 		return -1;
10941 
10942 	return skiplist_compare_text(oa->host_name, oa->service_description, ob->host_name, ob->service_description);
10943 	}
10944 
10945 
10946 
xodtemplate_skiplist_compare_timeperiod_template(void * a,void * b)10947 int xodtemplate_skiplist_compare_timeperiod_template(void *a, void *b) {
10948 	xodtemplate_timeperiod *oa = NULL;
10949 	xodtemplate_timeperiod *ob = NULL;
10950 
10951 	oa = (xodtemplate_timeperiod *)a;
10952 	ob = (xodtemplate_timeperiod *)b;
10953 
10954 	if(oa == NULL && ob == NULL)
10955 		return 0;
10956 	if(oa == NULL)
10957 		return 1;
10958 	if(ob == NULL)
10959 		return -1;
10960 
10961 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
10962 	}
10963 
10964 
10965 
xodtemplate_skiplist_compare_timeperiod(void * a,void * b)10966 int xodtemplate_skiplist_compare_timeperiod(void *a, void *b) {
10967 	xodtemplate_timeperiod *oa = NULL;
10968 	xodtemplate_timeperiod *ob = NULL;
10969 
10970 	oa = (xodtemplate_timeperiod *)a;
10971 	ob = (xodtemplate_timeperiod *)b;
10972 
10973 	if(oa == NULL && ob == NULL)
10974 		return 0;
10975 	if(oa == NULL)
10976 		return 1;
10977 	if(ob == NULL)
10978 		return -1;
10979 
10980 	return skiplist_compare_text(oa->timeperiod_name, NULL, ob->timeperiod_name, NULL);
10981 	}
10982 
10983 
10984 
xodtemplate_skiplist_compare_command_template(void * a,void * b)10985 int xodtemplate_skiplist_compare_command_template(void *a, void *b) {
10986 	xodtemplate_command *oa = NULL;
10987 	xodtemplate_command *ob = NULL;
10988 
10989 	oa = (xodtemplate_command *)a;
10990 	ob = (xodtemplate_command *)b;
10991 
10992 	if(oa == NULL && ob == NULL)
10993 		return 0;
10994 	if(oa == NULL)
10995 		return 1;
10996 	if(ob == NULL)
10997 		return -1;
10998 
10999 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
11000 	}
11001 
11002 
11003 
xodtemplate_skiplist_compare_command(void * a,void * b)11004 int xodtemplate_skiplist_compare_command(void *a, void *b) {
11005 	xodtemplate_command *oa = NULL;
11006 	xodtemplate_command *ob = NULL;
11007 
11008 	oa = (xodtemplate_command *)a;
11009 	ob = (xodtemplate_command *)b;
11010 
11011 	if(oa == NULL && ob == NULL)
11012 		return 0;
11013 	if(oa == NULL)
11014 		return 1;
11015 	if(ob == NULL)
11016 		return -1;
11017 
11018 	return skiplist_compare_text(oa->command_name, NULL, ob->command_name, NULL);
11019 	}
11020 
11021 
11022 
xodtemplate_skiplist_compare_contact_template(void * a,void * b)11023 int xodtemplate_skiplist_compare_contact_template(void *a, void *b) {
11024 	xodtemplate_contact *oa = NULL;
11025 	xodtemplate_contact *ob = NULL;
11026 
11027 	oa = (xodtemplate_contact *)a;
11028 	ob = (xodtemplate_contact *)b;
11029 
11030 	if(oa == NULL && ob == NULL)
11031 		return 0;
11032 	if(oa == NULL)
11033 		return 1;
11034 	if(ob == NULL)
11035 		return -1;
11036 
11037 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
11038 	}
11039 
11040 
11041 
xodtemplate_skiplist_compare_contact(void * a,void * b)11042 int xodtemplate_skiplist_compare_contact(void *a, void *b) {
11043 	xodtemplate_contact *oa = NULL;
11044 	xodtemplate_contact *ob = NULL;
11045 
11046 	oa = (xodtemplate_contact *)a;
11047 	ob = (xodtemplate_contact *)b;
11048 
11049 	if(oa == NULL && ob == NULL)
11050 		return 0;
11051 	if(oa == NULL)
11052 		return 1;
11053 	if(ob == NULL)
11054 		return -1;
11055 
11056 	return skiplist_compare_text(oa->contact_name, NULL, ob->contact_name, NULL);
11057 	}
11058 
11059 
11060 
xodtemplate_skiplist_compare_contactgroup_template(void * a,void * b)11061 int xodtemplate_skiplist_compare_contactgroup_template(void *a, void *b) {
11062 	xodtemplate_contactgroup *oa = NULL;
11063 	xodtemplate_contactgroup *ob = NULL;
11064 
11065 	oa = (xodtemplate_contactgroup *)a;
11066 	ob = (xodtemplate_contactgroup *)b;
11067 
11068 	if(oa == NULL && ob == NULL)
11069 		return 0;
11070 	if(oa == NULL)
11071 		return 1;
11072 	if(ob == NULL)
11073 		return -1;
11074 
11075 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
11076 	}
11077 
11078 
11079 
xodtemplate_skiplist_compare_contactgroup(void * a,void * b)11080 int xodtemplate_skiplist_compare_contactgroup(void *a, void *b) {
11081 	xodtemplate_contactgroup *oa = NULL;
11082 	xodtemplate_contactgroup *ob = NULL;
11083 
11084 	oa = (xodtemplate_contactgroup *)a;
11085 	ob = (xodtemplate_contactgroup *)b;
11086 
11087 	if(oa == NULL && ob == NULL)
11088 		return 0;
11089 	if(oa == NULL)
11090 		return 1;
11091 	if(ob == NULL)
11092 		return -1;
11093 
11094 	return skiplist_compare_text(oa->contactgroup_name, NULL, ob->contactgroup_name, NULL);
11095 	}
11096 
11097 
11098 
xodtemplate_skiplist_compare_hostgroup_template(void * a,void * b)11099 int xodtemplate_skiplist_compare_hostgroup_template(void *a, void *b) {
11100 	xodtemplate_hostgroup *oa = NULL;
11101 	xodtemplate_hostgroup *ob = NULL;
11102 
11103 	oa = (xodtemplate_hostgroup *)a;
11104 	ob = (xodtemplate_hostgroup *)b;
11105 
11106 	if(oa == NULL && ob == NULL)
11107 		return 0;
11108 	if(oa == NULL)
11109 		return 1;
11110 	if(ob == NULL)
11111 		return -1;
11112 
11113 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
11114 	}
11115 
11116 
11117 
xodtemplate_skiplist_compare_hostgroup(void * a,void * b)11118 int xodtemplate_skiplist_compare_hostgroup(void *a, void *b) {
11119 	xodtemplate_hostgroup *oa = NULL;
11120 	xodtemplate_hostgroup *ob = NULL;
11121 
11122 	oa = (xodtemplate_hostgroup *)a;
11123 	ob = (xodtemplate_hostgroup *)b;
11124 
11125 	if(oa == NULL && ob == NULL)
11126 		return 0;
11127 	if(oa == NULL)
11128 		return 1;
11129 	if(ob == NULL)
11130 		return -1;
11131 
11132 	return skiplist_compare_text(oa->hostgroup_name, NULL, ob->hostgroup_name, NULL);
11133 	}
11134 
11135 
11136 
xodtemplate_skiplist_compare_servicegroup_template(void * a,void * b)11137 int xodtemplate_skiplist_compare_servicegroup_template(void *a, void *b) {
11138 	xodtemplate_servicegroup *oa = NULL;
11139 	xodtemplate_servicegroup *ob = NULL;
11140 
11141 	oa = (xodtemplate_servicegroup *)a;
11142 	ob = (xodtemplate_servicegroup *)b;
11143 
11144 	if(oa == NULL && ob == NULL)
11145 		return 0;
11146 	if(oa == NULL)
11147 		return 1;
11148 	if(ob == NULL)
11149 		return -1;
11150 
11151 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
11152 	}
11153 
11154 
11155 
xodtemplate_skiplist_compare_servicegroup(void * a,void * b)11156 int xodtemplate_skiplist_compare_servicegroup(void *a, void *b) {
11157 	xodtemplate_servicegroup *oa = NULL;
11158 	xodtemplate_servicegroup *ob = NULL;
11159 
11160 	oa = (xodtemplate_servicegroup *)a;
11161 	ob = (xodtemplate_servicegroup *)b;
11162 
11163 	if(oa == NULL && ob == NULL)
11164 		return 0;
11165 	if(oa == NULL)
11166 		return 1;
11167 	if(ob == NULL)
11168 		return -1;
11169 
11170 	return skiplist_compare_text(oa->servicegroup_name, NULL, ob->servicegroup_name, NULL);
11171 	}
11172 
11173 
11174 
xodtemplate_skiplist_compare_hostdependency_template(void * a,void * b)11175 int xodtemplate_skiplist_compare_hostdependency_template(void *a, void *b) {
11176 	xodtemplate_hostdependency *oa = NULL;
11177 	xodtemplate_hostdependency *ob = NULL;
11178 
11179 	oa = (xodtemplate_hostdependency *)a;
11180 	ob = (xodtemplate_hostdependency *)b;
11181 
11182 	if(oa == NULL && ob == NULL)
11183 		return 0;
11184 	if(oa == NULL)
11185 		return 1;
11186 	if(ob == NULL)
11187 		return -1;
11188 
11189 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
11190 	}
11191 
11192 
11193 
xodtemplate_skiplist_compare_hostdependency(void * a,void * b)11194 int xodtemplate_skiplist_compare_hostdependency(void *a, void *b) {
11195 	xodtemplate_hostdependency *oa = NULL;
11196 	xodtemplate_hostdependency *ob = NULL;
11197 
11198 	oa = (xodtemplate_hostdependency *)a;
11199 	ob = (xodtemplate_hostdependency *)b;
11200 
11201 	if(oa == NULL && ob == NULL)
11202 		return 0;
11203 	if(oa == NULL)
11204 		return 1;
11205 	if(ob == NULL)
11206 		return -1;
11207 
11208 	return skiplist_compare_text(oa->dependent_host_name, NULL, ob->dependent_host_name, NULL);
11209 	}
11210 
11211 
11212 
xodtemplate_skiplist_compare_servicedependency_template(void * a,void * b)11213 int xodtemplate_skiplist_compare_servicedependency_template(void *a, void *b) {
11214 	xodtemplate_servicedependency *oa = NULL;
11215 	xodtemplate_servicedependency *ob = NULL;
11216 
11217 	oa = (xodtemplate_servicedependency *)a;
11218 	ob = (xodtemplate_servicedependency *)b;
11219 
11220 	if(oa == NULL && ob == NULL)
11221 		return 0;
11222 	if(oa == NULL)
11223 		return 1;
11224 	if(ob == NULL)
11225 		return -1;
11226 
11227 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
11228 	}
11229 
11230 
11231 
xodtemplate_skiplist_compare_servicedependency(void * a,void * b)11232 int xodtemplate_skiplist_compare_servicedependency(void *a, void *b) {
11233 	xodtemplate_servicedependency *oa = NULL;
11234 	xodtemplate_servicedependency *ob = NULL;
11235 
11236 	oa = (xodtemplate_servicedependency *)a;
11237 	ob = (xodtemplate_servicedependency *)b;
11238 
11239 	if(oa == NULL && ob == NULL)
11240 		return 0;
11241 	if(oa == NULL)
11242 		return 1;
11243 	if(ob == NULL)
11244 		return -1;
11245 
11246 	return skiplist_compare_text(oa->dependent_host_name, oa->dependent_service_description, ob->dependent_host_name, ob->dependent_service_description);
11247 	}
11248 
11249 
11250 
xodtemplate_skiplist_compare_hostescalation_template(void * a,void * b)11251 int xodtemplate_skiplist_compare_hostescalation_template(void *a, void *b) {
11252 	xodtemplate_hostescalation *oa = NULL;
11253 	xodtemplate_hostescalation *ob = NULL;
11254 
11255 	oa = (xodtemplate_hostescalation *)a;
11256 	ob = (xodtemplate_hostescalation *)b;
11257 
11258 	if(oa == NULL && ob == NULL)
11259 		return 0;
11260 	if(oa == NULL)
11261 		return 1;
11262 	if(ob == NULL)
11263 		return -1;
11264 
11265 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
11266 	}
11267 
11268 
11269 
xodtemplate_skiplist_compare_hostescalation(void * a,void * b)11270 int xodtemplate_skiplist_compare_hostescalation(void *a, void *b) {
11271 	xodtemplate_hostescalation *oa = NULL;
11272 	xodtemplate_hostescalation *ob = NULL;
11273 
11274 	oa = (xodtemplate_hostescalation *)a;
11275 	ob = (xodtemplate_hostescalation *)b;
11276 
11277 	if(oa == NULL && ob == NULL)
11278 		return 0;
11279 	if(oa == NULL)
11280 		return 1;
11281 	if(ob == NULL)
11282 		return -1;
11283 
11284 	return skiplist_compare_text(oa->host_name, NULL, ob->host_name, NULL);
11285 	}
11286 
11287 
11288 
xodtemplate_skiplist_compare_serviceescalation_template(void * a,void * b)11289 int xodtemplate_skiplist_compare_serviceescalation_template(void *a, void *b) {
11290 	xodtemplate_serviceescalation *oa = NULL;
11291 	xodtemplate_serviceescalation *ob = NULL;
11292 
11293 	oa = (xodtemplate_serviceescalation *)a;
11294 	ob = (xodtemplate_serviceescalation *)b;
11295 
11296 	if(oa == NULL && ob == NULL)
11297 		return 0;
11298 	if(oa == NULL)
11299 		return 1;
11300 	if(ob == NULL)
11301 		return -1;
11302 
11303 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
11304 	}
11305 
11306 
11307 
xodtemplate_skiplist_compare_serviceescalation(void * a,void * b)11308 int xodtemplate_skiplist_compare_serviceescalation(void *a, void *b) {
11309 	xodtemplate_serviceescalation *oa = NULL;
11310 	xodtemplate_serviceescalation *ob = NULL;
11311 
11312 	oa = (xodtemplate_serviceescalation *)a;
11313 	ob = (xodtemplate_serviceescalation *)b;
11314 
11315 	if(oa == NULL && ob == NULL)
11316 		return 0;
11317 	if(oa == NULL)
11318 		return 1;
11319 	if(ob == NULL)
11320 		return -1;
11321 
11322 	return skiplist_compare_text(oa->host_name, oa->service_description, ob->host_name, ob->service_description);
11323 	}
11324 
11325 
11326 
xodtemplate_skiplist_compare_hostextinfo_template(void * a,void * b)11327 int xodtemplate_skiplist_compare_hostextinfo_template(void *a, void *b) {
11328 	xodtemplate_hostextinfo *oa = NULL;
11329 	xodtemplate_hostextinfo *ob = NULL;
11330 
11331 	oa = (xodtemplate_hostextinfo *)a;
11332 	ob = (xodtemplate_hostextinfo *)b;
11333 
11334 	if(oa == NULL && ob == NULL)
11335 		return 0;
11336 	if(oa == NULL)
11337 		return 1;
11338 	if(ob == NULL)
11339 		return -1;
11340 
11341 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
11342 	}
11343 
11344 
11345 
xodtemplate_skiplist_compare_serviceextinfo_template(void * a,void * b)11346 int xodtemplate_skiplist_compare_serviceextinfo_template(void *a, void *b) {
11347 	xodtemplate_serviceextinfo *oa = NULL;
11348 	xodtemplate_serviceextinfo *ob = NULL;
11349 
11350 	oa = (xodtemplate_serviceextinfo *)a;
11351 	ob = (xodtemplate_serviceextinfo *)b;
11352 
11353 	if(oa == NULL && ob == NULL)
11354 		return 0;
11355 	if(oa == NULL)
11356 		return 1;
11357 	if(ob == NULL)
11358 		return -1;
11359 
11360 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
11361 	}
11362 
11363 
11364 
11365 
11366 /******************************************************************/
11367 /********************** CLEANUP FUNCTIONS *************************/
11368 /******************************************************************/
11369 
11370 /* frees memory */
xodtemplate_free_memory(void)11371 int xodtemplate_free_memory(void) {
11372 	xodtemplate_timeperiod *this_timeperiod = NULL;
11373 	xodtemplate_timeperiod *next_timeperiod = NULL;
11374 	xodtemplate_daterange *this_daterange = NULL;
11375 	xodtemplate_daterange *next_daterange = NULL;
11376 	xodtemplate_command *this_command = NULL;
11377 	xodtemplate_command *next_command = NULL;
11378 	xodtemplate_contactgroup *this_contactgroup = NULL;
11379 	xodtemplate_contactgroup *next_contactgroup = NULL;
11380 	xodtemplate_hostgroup *this_hostgroup = NULL;
11381 	xodtemplate_hostgroup *next_hostgroup = NULL;
11382 	xodtemplate_servicegroup *this_servicegroup = NULL;
11383 	xodtemplate_servicegroup *next_servicegroup = NULL;
11384 	xodtemplate_servicedependency *this_servicedependency = NULL;
11385 	xodtemplate_servicedependency *next_servicedependency = NULL;
11386 	xodtemplate_serviceescalation *this_serviceescalation = NULL;
11387 	xodtemplate_serviceescalation *next_serviceescalation = NULL;
11388 	xodtemplate_contact *this_contact = NULL;
11389 	xodtemplate_contact *next_contact = NULL;
11390 	xodtemplate_host *this_host = NULL;
11391 	xodtemplate_host *next_host = NULL;
11392 	xodtemplate_service *this_service = NULL;
11393 	xodtemplate_service *next_service = NULL;
11394 	xodtemplate_hostdependency *this_hostdependency = NULL;
11395 	xodtemplate_hostdependency *next_hostdependency = NULL;
11396 	xodtemplate_hostescalation *this_hostescalation = NULL;
11397 	xodtemplate_hostescalation *next_hostescalation = NULL;
11398 	xodtemplate_hostextinfo *this_hostextinfo = NULL;
11399 	xodtemplate_hostextinfo *next_hostextinfo = NULL;
11400 	xodtemplate_serviceextinfo *this_serviceextinfo = NULL;
11401 	xodtemplate_serviceextinfo *next_serviceextinfo = NULL;
11402 	xodtemplate_customvariablesmember *this_customvariablesmember = NULL;
11403 	xodtemplate_customvariablesmember *next_customvariablesmember = NULL;
11404 	register int x = 0;
11405 
11406 
11407 	/* free memory allocated to timeperiod list */
11408 	for(this_timeperiod = xodtemplate_timeperiod_list; this_timeperiod != NULL; this_timeperiod = next_timeperiod) {
11409 		next_timeperiod = this_timeperiod->next;
11410 		my_free(this_timeperiod->template);
11411 		my_free(this_timeperiod->name);
11412 		my_free(this_timeperiod->timeperiod_name);
11413 		my_free(this_timeperiod->alias);
11414 		for(x = 0; x < 7; x++)
11415 			my_free(this_timeperiod->timeranges[x]);
11416 		for(x = 0; x < DATERANGE_TYPES; x++) {
11417 			for(this_daterange = this_timeperiod->exceptions[x]; this_daterange != NULL; this_daterange = next_daterange) {
11418 				next_daterange = this_daterange->next;
11419 				my_free(this_daterange->timeranges);
11420 				my_free(this_daterange);
11421 				}
11422 			}
11423 		my_free(this_timeperiod->exclusions);
11424 		my_free(this_timeperiod);
11425 		}
11426 	xodtemplate_timeperiod_list = NULL;
11427 	xodtemplate_timeperiod_list_tail = NULL;
11428 
11429 	/* free memory allocated to command list */
11430 	for(this_command = xodtemplate_command_list; this_command != NULL; this_command = next_command) {
11431 		next_command = this_command->next;
11432 		my_free(this_command->template);
11433 		my_free(this_command->name);
11434 		my_free(this_command->command_name);
11435 		my_free(this_command->command_line);
11436 		my_free(this_command);
11437 		}
11438 	xodtemplate_command_list = NULL;
11439 	xodtemplate_command_list_tail = NULL;
11440 
11441 	/* free memory allocated to contactgroup list */
11442 	for(this_contactgroup = xodtemplate_contactgroup_list; this_contactgroup != NULL; this_contactgroup = next_contactgroup) {
11443 		next_contactgroup = this_contactgroup->next;
11444 		my_free(this_contactgroup->template);
11445 		my_free(this_contactgroup->name);
11446 		my_free(this_contactgroup->contactgroup_name);
11447 		my_free(this_contactgroup->alias);
11448 		my_free(this_contactgroup->members);
11449 		my_free(this_contactgroup->contactgroup_members);
11450 		my_free(this_contactgroup);
11451 		}
11452 	xodtemplate_contactgroup_list = NULL;
11453 	xodtemplate_contactgroup_list_tail = NULL;
11454 
11455 	/* free memory allocated to hostgroup list */
11456 	for(this_hostgroup = xodtemplate_hostgroup_list; this_hostgroup != NULL; this_hostgroup = next_hostgroup) {
11457 		next_hostgroup = this_hostgroup->next;
11458 		my_free(this_hostgroup->template);
11459 		my_free(this_hostgroup->name);
11460 		my_free(this_hostgroup->hostgroup_name);
11461 		my_free(this_hostgroup->alias);
11462 		my_free(this_hostgroup->members);
11463 		my_free(this_hostgroup->hostgroup_members);
11464 		my_free(this_hostgroup->notes);
11465 		my_free(this_hostgroup->notes_url);
11466 		my_free(this_hostgroup->action_url);
11467 		my_free(this_hostgroup);
11468 		}
11469 	xodtemplate_hostgroup_list = NULL;
11470 	xodtemplate_hostgroup_list_tail = NULL;
11471 
11472 	/* free memory allocated to servicegroup list */
11473 	for(this_servicegroup = xodtemplate_servicegroup_list; this_servicegroup != NULL; this_servicegroup = next_servicegroup) {
11474 		next_servicegroup = this_servicegroup->next;
11475 		my_free(this_servicegroup->template);
11476 		my_free(this_servicegroup->name);
11477 		my_free(this_servicegroup->servicegroup_name);
11478 		my_free(this_servicegroup->alias);
11479 		my_free(this_servicegroup->members);
11480 		my_free(this_servicegroup->servicegroup_members);
11481 		my_free(this_servicegroup->notes);
11482 		my_free(this_servicegroup->notes_url);
11483 		my_free(this_servicegroup->action_url);
11484 		my_free(this_servicegroup);
11485 		}
11486 	xodtemplate_servicegroup_list = NULL;
11487 	xodtemplate_servicegroup_list_tail = NULL;
11488 
11489 	/* free memory allocated to servicedependency list */
11490 	for(this_servicedependency = xodtemplate_servicedependency_list; this_servicedependency != NULL; this_servicedependency = next_servicedependency) {
11491 		next_servicedependency = this_servicedependency->next;
11492 		my_free(this_servicedependency->template);
11493 		my_free(this_servicedependency->name);
11494 		my_free(this_servicedependency->servicegroup_name);
11495 		my_free(this_servicedependency->hostgroup_name);
11496 		my_free(this_servicedependency->host_name);
11497 		my_free(this_servicedependency->service_description);
11498 		my_free(this_servicedependency->dependent_servicegroup_name);
11499 		my_free(this_servicedependency->dependent_hostgroup_name);
11500 		my_free(this_servicedependency->dependent_host_name);
11501 		my_free(this_servicedependency->dependent_service_description);
11502 		my_free(this_servicedependency->dependency_period);
11503 		my_free(this_servicedependency);
11504 		}
11505 	xodtemplate_servicedependency_list = NULL;
11506 	xodtemplate_servicedependency_list_tail = NULL;
11507 
11508 	/* free memory allocated to serviceescalation list */
11509 	for(this_serviceescalation = xodtemplate_serviceescalation_list; this_serviceescalation != NULL; this_serviceescalation = next_serviceescalation) {
11510 		next_serviceescalation = this_serviceescalation->next;
11511 		my_free(this_serviceescalation->template);
11512 		my_free(this_serviceescalation->name);
11513 		my_free(this_serviceescalation->servicegroup_name);
11514 		my_free(this_serviceescalation->hostgroup_name);
11515 		my_free(this_serviceescalation->host_name);
11516 		my_free(this_serviceescalation->service_description);
11517 		my_free(this_serviceescalation->escalation_period);
11518 		my_free(this_serviceescalation->contact_groups);
11519 		my_free(this_serviceescalation->contacts);
11520 		my_free(this_serviceescalation);
11521 		}
11522 	xodtemplate_serviceescalation_list = NULL;
11523 	xodtemplate_serviceescalation_list_tail = NULL;
11524 
11525 	/* free memory allocated to contact list */
11526 	for(this_contact = xodtemplate_contact_list; this_contact != NULL; this_contact = next_contact) {
11527 
11528 		/* free custom variables */
11529 		this_customvariablesmember = this_contact->custom_variables;
11530 		while(this_customvariablesmember != NULL) {
11531 			next_customvariablesmember = this_customvariablesmember->next;
11532 			my_free(this_customvariablesmember->variable_name);
11533 			my_free(this_customvariablesmember->variable_value);
11534 			my_free(this_customvariablesmember);
11535 			this_customvariablesmember = next_customvariablesmember;
11536 			}
11537 
11538 		next_contact = this_contact->next;
11539 		my_free(this_contact->template);
11540 		my_free(this_contact->name);
11541 		my_free(this_contact->contact_name);
11542 		my_free(this_contact->alias);
11543 		my_free(this_contact->contact_groups);
11544 		my_free(this_contact->email);
11545 		my_free(this_contact->pager);
11546 		for(x = 0; x < MAX_XODTEMPLATE_CONTACT_ADDRESSES; x++)
11547 			my_free(this_contact->address[x]);
11548 		my_free(this_contact->service_notification_period);
11549 		my_free(this_contact->service_notification_commands);
11550 		my_free(this_contact->host_notification_period);
11551 		my_free(this_contact->host_notification_commands);
11552 		my_free(this_contact);
11553 		}
11554 	xodtemplate_contact_list = NULL;
11555 	xodtemplate_contact_list_tail = NULL;
11556 
11557 	/* free memory allocated to host list */
11558 	for(this_host = xodtemplate_host_list; this_host != NULL; this_host = next_host) {
11559 
11560 		/* free custom variables */
11561 		this_customvariablesmember = this_host->custom_variables;
11562 		while(this_customvariablesmember != NULL) {
11563 			next_customvariablesmember = this_customvariablesmember->next;
11564 			my_free(this_customvariablesmember->variable_name);
11565 			my_free(this_customvariablesmember->variable_value);
11566 			my_free(this_customvariablesmember);
11567 			this_customvariablesmember = next_customvariablesmember;
11568 			}
11569 
11570 		next_host = this_host->next;
11571 		my_free(this_host->template);
11572 		my_free(this_host->name);
11573 		my_free(this_host->host_name);
11574 		my_free(this_host->alias);
11575 		my_free(this_host->display_name);
11576 		my_free(this_host->address);
11577 		my_free(this_host->parents);
11578 		my_free(this_host->host_groups);
11579 		my_free(this_host->check_command);
11580 		my_free(this_host->check_period);
11581 		my_free(this_host->event_handler);
11582 		my_free(this_host->contact_groups);
11583 		my_free(this_host->contacts);
11584 		my_free(this_host->notification_period);
11585 		my_free(this_host->failure_prediction_options);
11586 		my_free(this_host->notes);
11587 		my_free(this_host->notes_url);
11588 		my_free(this_host->action_url);
11589 		my_free(this_host->icon_image);
11590 		my_free(this_host->icon_image_alt);
11591 		my_free(this_host->vrml_image);
11592 		my_free(this_host->statusmap_image);
11593 		my_free(this_host);
11594 		}
11595 	xodtemplate_host_list = NULL;
11596 	xodtemplate_host_list_tail = NULL;
11597 
11598 	/* free memory allocated to service list */
11599 	for(this_service = xodtemplate_service_list; this_service != NULL; this_service = next_service) {
11600 
11601 		/* free custom variables */
11602 		this_customvariablesmember = this_service->custom_variables;
11603 		while(this_customvariablesmember != NULL) {
11604 			next_customvariablesmember = this_customvariablesmember->next;
11605 			my_free(this_customvariablesmember->variable_name);
11606 			my_free(this_customvariablesmember->variable_value);
11607 			my_free(this_customvariablesmember);
11608 			this_customvariablesmember = next_customvariablesmember;
11609 			}
11610 
11611 		next_service = this_service->next;
11612 		my_free(this_service->template);
11613 		my_free(this_service->name);
11614 		my_free(this_service->display_name);
11615 		my_free(this_service->hostgroup_name);
11616 		my_free(this_service->host_name);
11617 		my_free(this_service->service_description);
11618 		my_free(this_service->service_groups);
11619 		my_free(this_service->check_command);
11620 		my_free(this_service->check_period);
11621 		my_free(this_service->event_handler);
11622 		my_free(this_service->notification_period);
11623 		my_free(this_service->contact_groups);
11624 		my_free(this_service->contacts);
11625 		my_free(this_service->failure_prediction_options);
11626 		my_free(this_service->notes);
11627 		my_free(this_service->notes_url);
11628 		my_free(this_service->action_url);
11629 		my_free(this_service->icon_image);
11630 		my_free(this_service->icon_image_alt);
11631 		my_free(this_service);
11632 		}
11633 	xodtemplate_service_list = NULL;
11634 	xodtemplate_service_list_tail = NULL;
11635 
11636 	/* free memory allocated to hostdependency list */
11637 	for(this_hostdependency = xodtemplate_hostdependency_list; this_hostdependency != NULL; this_hostdependency = next_hostdependency) {
11638 		next_hostdependency = this_hostdependency->next;
11639 		my_free(this_hostdependency->template);
11640 		my_free(this_hostdependency->name);
11641 		my_free(this_hostdependency->hostgroup_name);
11642 		my_free(this_hostdependency->dependent_hostgroup_name);
11643 		my_free(this_hostdependency->host_name);
11644 		my_free(this_hostdependency->dependent_host_name);
11645 		my_free(this_hostdependency->dependency_period);
11646 		my_free(this_hostdependency);
11647 		}
11648 	xodtemplate_hostdependency_list = NULL;
11649 	xodtemplate_hostdependency_list_tail = NULL;
11650 
11651 	/* free memory allocated to hostescalation list */
11652 	for(this_hostescalation = xodtemplate_hostescalation_list; this_hostescalation != NULL; this_hostescalation = next_hostescalation) {
11653 		next_hostescalation = this_hostescalation->next;
11654 		my_free(this_hostescalation->template);
11655 		my_free(this_hostescalation->name);
11656 		my_free(this_hostescalation->hostgroup_name);
11657 		my_free(this_hostescalation->host_name);
11658 		my_free(this_hostescalation->escalation_period);
11659 		my_free(this_hostescalation->contact_groups);
11660 		my_free(this_hostescalation->contacts);
11661 		my_free(this_hostescalation);
11662 		}
11663 	xodtemplate_hostescalation_list = NULL;
11664 	xodtemplate_hostescalation_list_tail = NULL;
11665 
11666 	/* free memory allocated to hostextinfo list */
11667 	for(this_hostextinfo = xodtemplate_hostextinfo_list; this_hostextinfo != NULL; this_hostextinfo = next_hostextinfo) {
11668 		next_hostextinfo = this_hostextinfo->next;
11669 		my_free(this_hostextinfo->template);
11670 		my_free(this_hostextinfo->name);
11671 		my_free(this_hostextinfo->host_name);
11672 		my_free(this_hostextinfo->hostgroup_name);
11673 		my_free(this_hostextinfo->notes);
11674 		my_free(this_hostextinfo->notes_url);
11675 		my_free(this_hostextinfo->action_url);
11676 		my_free(this_hostextinfo->icon_image);
11677 		my_free(this_hostextinfo->icon_image_alt);
11678 		my_free(this_hostextinfo->vrml_image);
11679 		my_free(this_hostextinfo->statusmap_image);
11680 		my_free(this_hostextinfo);
11681 		}
11682 	xodtemplate_hostextinfo_list = NULL;
11683 	xodtemplate_hostextinfo_list_tail = NULL;
11684 
11685 	/* free memory allocated to serviceextinfo list */
11686 	for(this_serviceextinfo = xodtemplate_serviceextinfo_list; this_serviceextinfo != NULL; this_serviceextinfo = next_serviceextinfo) {
11687 		next_serviceextinfo = this_serviceextinfo->next;
11688 		my_free(this_serviceextinfo->template);
11689 		my_free(this_serviceextinfo->name);
11690 		my_free(this_serviceextinfo->host_name);
11691 		my_free(this_serviceextinfo->hostgroup_name);
11692 		my_free(this_serviceextinfo->service_description);
11693 		my_free(this_serviceextinfo->notes);
11694 		my_free(this_serviceextinfo->notes_url);
11695 		my_free(this_serviceextinfo->action_url);
11696 		my_free(this_serviceextinfo->icon_image);
11697 		my_free(this_serviceextinfo->icon_image_alt);
11698 		my_free(this_serviceextinfo);
11699 		}
11700 	xodtemplate_serviceextinfo_list = NULL;
11701 	xodtemplate_serviceextinfo_list_tail = NULL;
11702 
11703 	/* free memory for the config file names */
11704 	for(x = 0; x < xodtemplate_current_config_file; x++)
11705 		my_free(xodtemplate_config_files[x]);
11706 	my_free(xodtemplate_config_files);
11707 	xodtemplate_current_config_file = 0;
11708 
11709 	/* free skiplists */
11710 	xodtemplate_free_xobject_skiplists();
11711 
11712 	return OK;
11713 	}
11714 
11715 
11716 
11717 
11718 #ifdef NSCORE
11719 /* adds a member to a list */
xodtemplate_add_member_to_memberlist(xodtemplate_memberlist ** list,char * name1,char * name2)11720 int xodtemplate_add_member_to_memberlist(xodtemplate_memberlist **list, char *name1, char *name2) {
11721 	xodtemplate_memberlist *temp_item = NULL;
11722 	xodtemplate_memberlist *new_item = NULL;
11723 	int error = FALSE;
11724 
11725 	if(list == NULL)
11726 		return ERROR;
11727 	if(name1 == NULL)
11728 		return ERROR;
11729 
11730 	/* skip this member if its already in the list */
11731 	for(temp_item = *list; temp_item; temp_item = temp_item->next) {
11732 		if(!strcmp(temp_item->name1, name1)) {
11733 			if(temp_item->name2 == NULL) {
11734 				if(name2 == NULL)
11735 					break;
11736 				}
11737 			else if(name2 != NULL && !strcmp(temp_item->name2, name2))
11738 				break;
11739 			}
11740 		}
11741 	if(temp_item)
11742 		return OK;
11743 
11744 	/* allocate zero'd out memory for a new list item */
11745 	if((new_item = (xodtemplate_memberlist *)calloc(1, sizeof(xodtemplate_memberlist))) == NULL)
11746 		return ERROR;
11747 
11748 	/* save the member name(s) */
11749 	if(name1) {
11750 		if((new_item->name1 = (char *)strdup(name1)) == NULL)
11751 			error = TRUE;
11752 		}
11753 	if(name2) {
11754 		if((new_item->name2 = (char *)strdup(name2)) == NULL)
11755 			error = TRUE;
11756 		}
11757 
11758 	if(error == TRUE) {
11759 		my_free(new_item->name1);
11760 		my_free(new_item->name2);
11761 		my_free(new_item);
11762 		return ERROR;
11763 		}
11764 
11765 	/* add new item to head of list */
11766 	new_item->next = *list;
11767 	*list = new_item;
11768 
11769 	return OK;
11770 	}
11771 
11772 
11773 /* frees memory allocated to a temporary member list */
xodtemplate_free_memberlist(xodtemplate_memberlist ** temp_list)11774 int xodtemplate_free_memberlist(xodtemplate_memberlist **temp_list) {
11775 	xodtemplate_memberlist *this_memberlist = NULL;
11776 	xodtemplate_memberlist *next_memberlist = NULL;
11777 
11778 	/* free memory allocated to member name list */
11779 	for(this_memberlist = *temp_list; this_memberlist != NULL; this_memberlist = next_memberlist) {
11780 		next_memberlist = this_memberlist->next;
11781 		my_free(this_memberlist->name1);
11782 		my_free(this_memberlist->name2);
11783 		my_free(this_memberlist);
11784 		}
11785 
11786 	*temp_list = NULL;
11787 
11788 	return OK;
11789 	}
11790 
11791 
11792 /* remove an entry from the member list */
xodtemplate_remove_memberlist_item(xodtemplate_memberlist * item,xodtemplate_memberlist ** list)11793 void xodtemplate_remove_memberlist_item(xodtemplate_memberlist *item, xodtemplate_memberlist **list) {
11794 	xodtemplate_memberlist *temp_item = NULL;
11795 
11796 	if(item == NULL || list == NULL)
11797 		return;
11798 
11799 	if(*list == NULL)
11800 		return;
11801 
11802 	if(*list == item)
11803 		*list = item->next;
11804 
11805 	else {
11806 
11807 		for(temp_item = *list; temp_item != NULL; temp_item = temp_item->next) {
11808 			if(temp_item->next == item) {
11809 				temp_item->next = item->next;
11810 				break;
11811 				}
11812 			}
11813 		}
11814 
11815 	my_free(item->name1);
11816 	my_free(item->name2);
11817 	my_free(item);
11818 
11819 	return;
11820 	}
11821 #endif
11822 
11823 
11824 /******************************************************************/
11825 /********************** UTILITY FUNCTIONS *************************/
11826 /******************************************************************/
11827 
11828 #ifdef NSCORE
11829 
11830 /* expands a comma-delimited list of contactgroups and/or contacts to member contact names */
xodtemplate_expand_contactgroups_and_contacts(char * contactgroups,char * contacts,int _config_file,int _start_line)11831 xodtemplate_memberlist *xodtemplate_expand_contactgroups_and_contacts(char *contactgroups, char *contacts, int _config_file, int _start_line) {
11832 	xodtemplate_memberlist *temp_list = NULL;
11833 	xodtemplate_memberlist *reject_list = NULL;
11834 	xodtemplate_memberlist *list_ptr = NULL;
11835 	xodtemplate_memberlist *reject_ptr = NULL;
11836 	int result = OK;
11837 
11838 	/* process list of contactgroups... */
11839 	if(contactgroups != NULL) {
11840 
11841 		/* expand contactgroups */
11842 		result = xodtemplate_expand_contactgroups(&temp_list, &reject_list, contactgroups, _config_file, _start_line);
11843 		if(result != OK) {
11844 			xodtemplate_free_memberlist(&temp_list);
11845 			xodtemplate_free_memberlist(&reject_list);
11846 			return NULL;
11847 			}
11848 		}
11849 
11850 	/* process contact names */
11851 	if(contacts != NULL) {
11852 
11853 		/* expand contacts */
11854 		result = xodtemplate_expand_contacts(&temp_list, &reject_list, contacts, _config_file, _start_line);
11855 		if(result != OK) {
11856 			xodtemplate_free_memberlist(&temp_list);
11857 			xodtemplate_free_memberlist(&reject_list);
11858 			return NULL;
11859 			}
11860 		}
11861 
11862 	/* remove rejects (if any) from the list (no duplicate entries exist in either list) */
11863 	/* NOTE: rejects from this list also affect contacts generated from processing contactgroup names (see above) */
11864 	for(reject_ptr = reject_list; reject_ptr != NULL; reject_ptr = reject_ptr->next) {
11865 		for(list_ptr = temp_list; list_ptr != NULL; list_ptr = list_ptr->next) {
11866 			if(!strcmp(reject_ptr->name1, list_ptr->name1)) {
11867 				xodtemplate_remove_memberlist_item(list_ptr, &temp_list);
11868 				break;
11869 				}
11870 			}
11871 		}
11872 	xodtemplate_free_memberlist(&reject_list);
11873 	reject_list = NULL;
11874 
11875 	return temp_list;
11876 	}
11877 
11878 
11879 
11880 /* expands contactgroups */
xodtemplate_expand_contactgroups(xodtemplate_memberlist ** list,xodtemplate_memberlist ** reject_list,char * contactgroups,int _config_file,int _start_line)11881 int xodtemplate_expand_contactgroups(xodtemplate_memberlist **list, xodtemplate_memberlist **reject_list, char *contactgroups, int _config_file, int _start_line) {
11882 	char *contactgroup_names = NULL;
11883 	char *temp_ptr = NULL;
11884 	xodtemplate_contactgroup *temp_contactgroup = NULL;
11885 	regex_t preg;
11886 	int found_match = TRUE;
11887 	int reject_item = FALSE;
11888 	int use_regexp = FALSE;
11889 
11890 	if(list == NULL || contactgroups == NULL)
11891 		return ERROR;
11892 
11893 	/* allocate memory for contactgroup name list */
11894 	if((contactgroup_names = (char *)strdup(contactgroups)) == NULL)
11895 		return ERROR;
11896 
11897 	for(temp_ptr = strtok(contactgroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) {
11898 
11899 		found_match = FALSE;
11900 		reject_item = FALSE;
11901 
11902 		/* strip trailing spaces */
11903 		strip(temp_ptr);
11904 
11905 		/* should we use regular expression matching? */
11906 		if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\.")))
11907 			use_regexp = TRUE;
11908 		else
11909 			use_regexp = FALSE;
11910 
11911 		/* use regular expression matching */
11912 		if(use_regexp == TRUE) {
11913 
11914 			/* compile regular expression */
11915 			if(regcomp(&preg, temp_ptr, REG_EXTENDED)) {
11916 				my_free(contactgroup_names);
11917 				return ERROR;
11918 				}
11919 
11920 			/* test match against all contactgroup names */
11921 			for(temp_contactgroup = xodtemplate_contactgroup_list; temp_contactgroup != NULL; temp_contactgroup = temp_contactgroup->next) {
11922 
11923 				if(temp_contactgroup->contactgroup_name == NULL)
11924 					continue;
11925 
11926 				/* skip this contactgroup if it did not match the expression */
11927 				if(regexec(&preg, temp_contactgroup->contactgroup_name, 0, NULL, 0))
11928 					continue;
11929 
11930 				found_match = TRUE;
11931 
11932 				/* dont' add contactgroups that shouldn't be registered */
11933 				if(temp_contactgroup->register_object == FALSE)
11934 					continue;
11935 
11936 				/* add contactgroup members to list */
11937 				xodtemplate_add_contactgroup_members_to_memberlist(list, temp_contactgroup, _config_file, _start_line);
11938 				}
11939 
11940 			/* free memory allocated to compiled regexp */
11941 			regfree(&preg);
11942 			}
11943 
11944 		/* use standard matching... */
11945 		else {
11946 
11947 			/* return a list of all contactgroups */
11948 			if(!strcmp(temp_ptr, "*")) {
11949 
11950 				found_match = TRUE;
11951 
11952 				for(temp_contactgroup = xodtemplate_contactgroup_list; temp_contactgroup != NULL; temp_contactgroup = temp_contactgroup->next) {
11953 
11954 					/* dont' add contactgroups that shouldn't be registered */
11955 					if(temp_contactgroup->register_object == FALSE)
11956 						continue;
11957 
11958 					/* add contactgroup to list */
11959 					xodtemplate_add_contactgroup_members_to_memberlist(list, temp_contactgroup, _config_file, _start_line);
11960 					}
11961 				}
11962 
11963 			/* else this is just a single contactgroup... */
11964 			else {
11965 
11966 				/* this contactgroup should be excluded (rejected) */
11967 				if(temp_ptr[0] == '!') {
11968 					reject_item = TRUE;
11969 					temp_ptr++;
11970 					}
11971 
11972 				/* find the contactgroup */
11973 				temp_contactgroup = xodtemplate_find_real_contactgroup(temp_ptr);
11974 				if(temp_contactgroup != NULL) {
11975 
11976 					found_match = TRUE;
11977 
11978 					/* add contactgroup members to proper list */
11979 					xodtemplate_add_contactgroup_members_to_memberlist((reject_item == TRUE) ? reject_list : list, temp_contactgroup, _config_file, _start_line);
11980 					}
11981 				}
11982 			}
11983 
11984 		if(found_match == FALSE) {
11985 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find any contactgroup matching '%s' (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(_config_file), _start_line);
11986 			break;
11987 			}
11988 		}
11989 
11990 	/* free memory */
11991 	my_free(contactgroup_names);
11992 
11993 	if(found_match == FALSE)
11994 		return ERROR;
11995 
11996 	return OK;
11997 	}
11998 
11999 
12000 
12001 /* expands contacts */
xodtemplate_expand_contacts(xodtemplate_memberlist ** list,xodtemplate_memberlist ** reject_list,char * contacts,int _config_file,int _start_line)12002 int xodtemplate_expand_contacts(xodtemplate_memberlist **list, xodtemplate_memberlist **reject_list, char *contacts, int _config_file, int _start_line) {
12003 	char *contact_names = NULL;
12004 	char *temp_ptr = NULL;
12005 	xodtemplate_contact *temp_contact = NULL;
12006 	regex_t preg;
12007 	int found_match = TRUE;
12008 	int reject_item = FALSE;
12009 	int use_regexp = FALSE;
12010 
12011 	if(list == NULL || contacts == NULL)
12012 		return ERROR;
12013 
12014 	if((contact_names = (char *)strdup(contacts)) == NULL)
12015 		return ERROR;
12016 
12017 	/* expand each contact name */
12018 	for(temp_ptr = strtok(contact_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) {
12019 
12020 		found_match = FALSE;
12021 		reject_item = FALSE;
12022 
12023 		/* strip trailing spaces */
12024 		strip(temp_ptr);
12025 
12026 		/* should we use regular expression matching? */
12027 		if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\.")))
12028 			use_regexp = TRUE;
12029 
12030 		/* use regular expression matching */
12031 		if(use_regexp == TRUE) {
12032 
12033 			/* compile regular expression */
12034 			if(regcomp(&preg, temp_ptr, REG_EXTENDED)) {
12035 				my_free(contact_names);
12036 				return ERROR;
12037 				}
12038 
12039 			/* test match against all contacts */
12040 			for(temp_contact = xodtemplate_contact_list; temp_contact != NULL; temp_contact = temp_contact->next) {
12041 
12042 				if(temp_contact->contact_name == NULL)
12043 					continue;
12044 
12045 				/* skip this contact if it did not match the expression */
12046 				if(regexec(&preg, temp_contact->contact_name, 0, NULL, 0))
12047 					continue;
12048 
12049 				found_match = TRUE;
12050 
12051 				/* dont' add contacts that shouldn't be registered */
12052 				if(temp_contact->register_object == FALSE)
12053 					continue;
12054 
12055 				/* add contact to list */
12056 				xodtemplate_add_member_to_memberlist(list, temp_contact->contact_name, NULL);
12057 				}
12058 
12059 			/* free memory allocated to compiled regexp */
12060 			regfree(&preg);
12061 			}
12062 
12063 		/* use standard matching... */
12064 		else {
12065 
12066 			/* return a list of all contacts */
12067 			if(!strcmp(temp_ptr, "*")) {
12068 
12069 				found_match = TRUE;
12070 
12071 				for(temp_contact = xodtemplate_contact_list; temp_contact != NULL; temp_contact = temp_contact->next) {
12072 
12073 					if(temp_contact->contact_name == NULL)
12074 						continue;
12075 
12076 					/* dont' add contacts that shouldn't be registered */
12077 					if(temp_contact->register_object == FALSE)
12078 						continue;
12079 
12080 					/* add contact to list */
12081 					xodtemplate_add_member_to_memberlist(list, temp_contact->contact_name, NULL);
12082 					}
12083 				}
12084 
12085 			/* else this is just a single contact... */
12086 			else {
12087 
12088 				/* this contact should be excluded (rejected) */
12089 				if(temp_ptr[0] == '!') {
12090 					reject_item = TRUE;
12091 					temp_ptr++;
12092 					}
12093 
12094 				/* find the contact */
12095 				temp_contact = xodtemplate_find_real_contact(temp_ptr);
12096 				if(temp_contact != NULL) {
12097 
12098 					found_match = TRUE;
12099 
12100 					/* add contact to list */
12101 					xodtemplate_add_member_to_memberlist((reject_item == TRUE) ? reject_list : list, temp_ptr, NULL);
12102 					}
12103 				}
12104 			}
12105 
12106 		if(found_match == FALSE) {
12107 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find any contact matching '%s' (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(_config_file), _start_line);
12108 			break;
12109 			}
12110 		}
12111 
12112 	/* free memory */
12113 	my_free(contact_names);
12114 
12115 	if(found_match == FALSE)
12116 		return ERROR;
12117 
12118 	return OK;
12119 	}
12120 
12121 
12122 
12123 /* adds members of a contactgroups to the list of expanded (accepted) or rejected contacts */
xodtemplate_add_contactgroup_members_to_memberlist(xodtemplate_memberlist ** list,xodtemplate_contactgroup * temp_contactgroup,int _config_file,int _start_line)12124 int xodtemplate_add_contactgroup_members_to_memberlist(xodtemplate_memberlist **list, xodtemplate_contactgroup *temp_contactgroup, int _config_file, int _start_line) {
12125 	char *group_members = NULL;
12126 	char *member_name = NULL;
12127 	char *member_ptr = NULL;
12128 
12129 	if(list == NULL || temp_contactgroup == NULL)
12130 		return ERROR;
12131 
12132 	/* if we have no members, just return. Empty contactgroups are ok */
12133 	if(temp_contactgroup->members == NULL) {
12134 		return OK;
12135 		}
12136 
12137 	/* save a copy of the members */
12138 	if((group_members = (char *)strdup(temp_contactgroup->members)) == NULL)
12139 		return ERROR;
12140 
12141 	/* process all contacts that belong to the contactgroup */
12142 	/* NOTE: members of the group have already have been expanded by xodtemplate_recombobulate_contactgroups(), so we don't need to do it here */
12143 	member_ptr = group_members;
12144 	for(member_name = my_strsep(&member_ptr, ","); member_name != NULL; member_name = my_strsep(&member_ptr, ",")) {
12145 
12146 		/* strip trailing spaces from member name */
12147 		strip(member_name);
12148 
12149 		/* add contact to the list */
12150 		xodtemplate_add_member_to_memberlist(list, member_name, NULL);
12151 		}
12152 
12153 	my_free(group_members);
12154 
12155 	return OK;
12156 	}
12157 
12158 
12159 
12160 /* expands a comma-delimited list of hostgroups and/or hosts to member host names */
xodtemplate_expand_hostgroups_and_hosts(char * hostgroups,char * hosts,int _config_file,int _start_line)12161 xodtemplate_memberlist *xodtemplate_expand_hostgroups_and_hosts(char *hostgroups, char *hosts, int _config_file, int _start_line) {
12162 	xodtemplate_memberlist *temp_list = NULL;
12163 	xodtemplate_memberlist *reject_list = NULL;
12164 	xodtemplate_memberlist *list_ptr = NULL;
12165 	xodtemplate_memberlist *reject_ptr = NULL;
12166 	int result = OK;
12167 
12168 	/* process list of hostgroups... */
12169 	if(hostgroups != NULL) {
12170 
12171 		/* expand host */
12172 		result = xodtemplate_expand_hostgroups(&temp_list, &reject_list, hostgroups, _config_file, _start_line);
12173 		if(result != OK) {
12174 			xodtemplate_free_memberlist(&temp_list);
12175 			xodtemplate_free_memberlist(&reject_list);
12176 			return NULL;
12177 			}
12178 		}
12179 
12180 	/* process host names */
12181 	if(hosts != NULL) {
12182 
12183 		/* expand hosts */
12184 		result = xodtemplate_expand_hosts(&temp_list, &reject_list, hosts, _config_file, _start_line);
12185 		if(result != OK) {
12186 			xodtemplate_free_memberlist(&temp_list);
12187 			xodtemplate_free_memberlist(&reject_list);
12188 			return NULL;
12189 			}
12190 		}
12191 
12192 #ifdef TESTING
12193 	printf("->PRIOR TO CLEANUP\n");
12194 	printf("   REJECT LIST:\n");
12195 	for(list_ptr = reject_list; list_ptr != NULL; list_ptr = list_ptr->next) {
12196 		printf("      '%s'\n", list_ptr->name1);
12197 		}
12198 	printf("   ACCEPT LIST:\n");
12199 	for(list_ptr = temp_list; list_ptr != NULL; list_ptr = list_ptr->next) {
12200 		printf("      '%s'\n", list_ptr->name1);
12201 		}
12202 #endif
12203 
12204 	/* remove rejects (if any) from the list (no duplicate entries exist in either list) */
12205 	/* NOTE: rejects from this list also affect hosts generated from processing hostgroup names (see above) */
12206 	for(reject_ptr = reject_list; reject_ptr != NULL; reject_ptr = reject_ptr->next) {
12207 		for(list_ptr = temp_list; list_ptr != NULL; list_ptr = list_ptr->next) {
12208 			if(!strcmp(reject_ptr->name1, list_ptr->name1)) {
12209 				xodtemplate_remove_memberlist_item(list_ptr, &temp_list);
12210 				break;
12211 				}
12212 			}
12213 		}
12214 	xodtemplate_free_memberlist(&reject_list);
12215 	reject_list = NULL;
12216 
12217 	return temp_list;
12218 	}
12219 
12220 
12221 
12222 /* expands hostgroups */
xodtemplate_expand_hostgroups(xodtemplate_memberlist ** list,xodtemplate_memberlist ** reject_list,char * hostgroups,int _config_file,int _start_line)12223 int xodtemplate_expand_hostgroups(xodtemplate_memberlist **list, xodtemplate_memberlist **reject_list, char *hostgroups, int _config_file, int _start_line) {
12224 	char *hostgroup_names = NULL;
12225 	char *temp_ptr = NULL;
12226 	xodtemplate_hostgroup *temp_hostgroup = NULL;
12227 	regex_t preg;
12228 	int found_match = TRUE;
12229 	int reject_item = FALSE;
12230 	int use_regexp = FALSE;
12231 
12232 	if(list == NULL || hostgroups == NULL)
12233 		return ERROR;
12234 
12235 	/* allocate memory for hostgroup name list */
12236 	if((hostgroup_names = (char *)strdup(hostgroups)) == NULL)
12237 		return ERROR;
12238 
12239 	for(temp_ptr = strtok(hostgroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) {
12240 
12241 		found_match = FALSE;
12242 		reject_item = FALSE;
12243 
12244 		/* strip trailing spaces */
12245 		strip(temp_ptr);
12246 
12247 		/* should we use regular expression matching? */
12248 		if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\.")))
12249 			use_regexp = TRUE;
12250 		else
12251 			use_regexp = FALSE;
12252 
12253 		/* use regular expression matching */
12254 		if(use_regexp == TRUE) {
12255 
12256 			/* compile regular expression */
12257 			if(regcomp(&preg, temp_ptr, REG_EXTENDED)) {
12258 				my_free(hostgroup_names);
12259 				return ERROR;
12260 				}
12261 
12262 			/* test match against all hostgroup names */
12263 			for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) {
12264 
12265 				if(temp_hostgroup->hostgroup_name == NULL)
12266 					continue;
12267 
12268 				/* skip this hostgroup if it did not match the expression */
12269 				if(regexec(&preg, temp_hostgroup->hostgroup_name, 0, NULL, 0))
12270 					continue;
12271 
12272 				found_match = TRUE;
12273 
12274 				/* dont' add hostgroups that shouldn't be registered */
12275 				if(temp_hostgroup->register_object == FALSE)
12276 					continue;
12277 
12278 				/* add hostgroup members to list */
12279 				xodtemplate_add_hostgroup_members_to_memberlist(list, temp_hostgroup, _config_file, _start_line);
12280 				}
12281 
12282 			/* free memory allocated to compiled regexp */
12283 			regfree(&preg);
12284 			}
12285 
12286 		/* use standard matching... */
12287 		else {
12288 
12289 			/* return a list of all hostgroups */
12290 			if(!strcmp(temp_ptr, "*")) {
12291 
12292 				found_match = TRUE;
12293 
12294 				for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) {
12295 
12296 					/* dont' add hostgroups that shouldn't be registered */
12297 					if(temp_hostgroup->register_object == FALSE)
12298 						continue;
12299 
12300 					/* add hostgroup to list */
12301 					xodtemplate_add_hostgroup_members_to_memberlist(list, temp_hostgroup, _config_file, _start_line);
12302 					}
12303 				}
12304 
12305 			/* else this is just a single hostgroup... */
12306 			else {
12307 
12308 				/* this hostgroup should be excluded (rejected) */
12309 				if(temp_ptr[0] == '!') {
12310 					reject_item = TRUE;
12311 					temp_ptr++;
12312 					}
12313 
12314 				/* find the hostgroup */
12315 				temp_hostgroup = xodtemplate_find_real_hostgroup(temp_ptr);
12316 				if(temp_hostgroup != NULL) {
12317 
12318 					found_match = TRUE;
12319 
12320 					/* add hostgroup members to proper list */
12321 					xodtemplate_add_hostgroup_members_to_memberlist((reject_item == TRUE) ? reject_list : list, temp_hostgroup, _config_file, _start_line);
12322 					}
12323 				}
12324 			}
12325 
12326 		if(found_match == FALSE) {
12327 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find any hostgroup matching '%s' (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(_config_file), _start_line);
12328 			break;
12329 			}
12330 		}
12331 
12332 	/* free memory */
12333 	my_free(hostgroup_names);
12334 
12335 	if(found_match == FALSE)
12336 		return ERROR;
12337 
12338 	return OK;
12339 	}
12340 
12341 
12342 
12343 /* expands hosts */
xodtemplate_expand_hosts(xodtemplate_memberlist ** list,xodtemplate_memberlist ** reject_list,char * hosts,int _config_file,int _start_line)12344 int xodtemplate_expand_hosts(xodtemplate_memberlist **list, xodtemplate_memberlist **reject_list, char *hosts, int _config_file, int _start_line) {
12345 	char *host_names = NULL;
12346 	char *temp_ptr = NULL;
12347 	xodtemplate_host *temp_host = NULL;
12348 	regex_t preg;
12349 	int found_match = TRUE;
12350 	int reject_item = FALSE;
12351 	int use_regexp = FALSE;
12352 
12353 	if(list == NULL || hosts == NULL)
12354 		return ERROR;
12355 
12356 	if((host_names = (char *)strdup(hosts)) == NULL)
12357 		return ERROR;
12358 
12359 	/* expand each host name */
12360 	for(temp_ptr = strtok(host_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) {
12361 
12362 		found_match = FALSE;
12363 		reject_item = FALSE;
12364 
12365 		/* strip trailing spaces */
12366 		strip(temp_ptr);
12367 
12368 		/* should we use regular expression matching? */
12369 		if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\.")))
12370 			use_regexp = TRUE;
12371 
12372 		/* use regular expression matching */
12373 		if(use_regexp == TRUE) {
12374 
12375 			/* compile regular expression */
12376 			if(regcomp(&preg, temp_ptr, REG_EXTENDED)) {
12377 				my_free(host_names);
12378 				return ERROR;
12379 				}
12380 
12381 			/* test match against all hosts */
12382 			for(temp_host = xodtemplate_host_list; temp_host != NULL; temp_host = temp_host->next) {
12383 
12384 				if(temp_host->host_name == NULL)
12385 					continue;
12386 
12387 				/* skip this host if it did not match the expression */
12388 				if(regexec(&preg, temp_host->host_name, 0, NULL, 0))
12389 					continue;
12390 
12391 				found_match = TRUE;
12392 
12393 				/* dont' add hosts that shouldn't be registered */
12394 				if(temp_host->register_object == FALSE)
12395 					continue;
12396 
12397 				/* add host to list */
12398 				xodtemplate_add_member_to_memberlist(list, temp_host->host_name, NULL);
12399 				}
12400 
12401 			/* free memory allocated to compiled regexp */
12402 			regfree(&preg);
12403 			}
12404 
12405 		/* use standard matching... */
12406 		else {
12407 
12408 			/* return a list of all hosts */
12409 			if(!strcmp(temp_ptr, "*")) {
12410 
12411 				found_match = TRUE;
12412 
12413 				for(temp_host = xodtemplate_host_list; temp_host != NULL; temp_host = temp_host->next) {
12414 
12415 					if(temp_host->host_name == NULL)
12416 						continue;
12417 
12418 					/* dont' add hosts that shouldn't be registered */
12419 					if(temp_host->register_object == FALSE)
12420 						continue;
12421 
12422 					/* add host to list */
12423 					xodtemplate_add_member_to_memberlist(list, temp_host->host_name, NULL);
12424 					}
12425 				}
12426 
12427 			/* else this is just a single host... */
12428 			else {
12429 
12430 				/* this host should be excluded (rejected) */
12431 				if(temp_ptr[0] == '!') {
12432 					reject_item = TRUE;
12433 					temp_ptr++;
12434 					}
12435 
12436 				/* find the host */
12437 				temp_host = xodtemplate_find_real_host(temp_ptr);
12438 				if(temp_host != NULL) {
12439 
12440 					found_match = TRUE;
12441 
12442 					/* add host to list */
12443 					xodtemplate_add_member_to_memberlist((reject_item == TRUE) ? reject_list : list, temp_ptr, NULL);
12444 					}
12445 				}
12446 			}
12447 
12448 		if(found_match == FALSE) {
12449 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find any host matching '%s' (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(_config_file), _start_line);
12450 			break;
12451 			}
12452 		}
12453 
12454 	/* free memory */
12455 	my_free(host_names);
12456 
12457 	if(found_match == FALSE)
12458 		return ERROR;
12459 
12460 	return OK;
12461 	}
12462 
12463 
12464 /* adds members of a hostgroups to the list of expanded (accepted) or rejected hosts */
xodtemplate_add_hostgroup_members_to_memberlist(xodtemplate_memberlist ** list,xodtemplate_hostgroup * temp_hostgroup,int _config_file,int _start_line)12465 int xodtemplate_add_hostgroup_members_to_memberlist(xodtemplate_memberlist **list, xodtemplate_hostgroup *temp_hostgroup, int _config_file, int _start_line) {
12466 	char *group_members = NULL;
12467 	char *member_name = NULL;
12468 	char *member_ptr = NULL;
12469 
12470 	if(list == NULL || temp_hostgroup == NULL)
12471 		return ERROR;
12472 
12473 	/* if we have no members, just return. Empty hostgroups are ok */
12474 	if(temp_hostgroup->members == NULL) {
12475 		return OK;
12476 		}
12477 
12478 	/* save a copy of the members */
12479 	if((group_members = (char *)strdup(temp_hostgroup->members)) == NULL)
12480 		return ERROR;
12481 
12482 	/* process all hosts that belong to the hostgroup */
12483 	/* NOTE: members of the group have already have been expanded by xodtemplate_recombobulate_hostgroups(), so we don't need to do it here */
12484 	member_ptr = group_members;
12485 	for(member_name = my_strsep(&member_ptr, ","); member_name != NULL; member_name = my_strsep(&member_ptr, ",")) {
12486 
12487 		/* strip trailing spaces from member name */
12488 		strip(member_name);
12489 
12490 		/* add host to the list */
12491 		xodtemplate_add_member_to_memberlist(list, member_name, NULL);
12492 		}
12493 
12494 	my_free(group_members);
12495 
12496 	return OK;
12497 	}
12498 
12499 
12500 
12501 /* expands a comma-delimited list of servicegroups and/or service descriptions */
xodtemplate_expand_servicegroups_and_services(char * servicegroups,char * host_name,char * services,int _config_file,int _start_line)12502 xodtemplate_memberlist *xodtemplate_expand_servicegroups_and_services(char *servicegroups, char *host_name, char *services, int _config_file, int _start_line) {
12503 	xodtemplate_memberlist *temp_list = NULL;
12504 	xodtemplate_memberlist *reject_list = NULL;
12505 	xodtemplate_memberlist *list_ptr = NULL;
12506 	xodtemplate_memberlist *reject_ptr = NULL;
12507 	int result = OK;
12508 
12509 	/* process list of servicegroups... */
12510 	if(servicegroups != NULL) {
12511 
12512 		/* expand servicegroups */
12513 		result = xodtemplate_expand_servicegroups(&temp_list, &reject_list, servicegroups, _config_file, _start_line);
12514 		if(result != OK) {
12515 			xodtemplate_free_memberlist(&temp_list);
12516 			xodtemplate_free_memberlist(&reject_list);
12517 			return NULL;
12518 			}
12519 		}
12520 
12521 	/* process service names */
12522 	if(host_name != NULL && services != NULL) {
12523 
12524 		/* expand services */
12525 		result = xodtemplate_expand_services(&temp_list, &reject_list, host_name, services, _config_file, _start_line);
12526 		if(result != OK) {
12527 			xodtemplate_free_memberlist(&temp_list);
12528 			xodtemplate_free_memberlist(&reject_list);
12529 			return NULL;
12530 			}
12531 		}
12532 
12533 	/* remove rejects (if any) from the list (no duplicate entries exist in either list) */
12534 	/* NOTE: rejects from this list also affect hosts generated from processing hostgroup names (see above) */
12535 	for(reject_ptr = reject_list; reject_ptr != NULL; reject_ptr = reject_ptr->next) {
12536 		for(list_ptr = temp_list; list_ptr != NULL; list_ptr = list_ptr->next) {
12537 			if(!strcmp(reject_ptr->name1, list_ptr->name1) && !strcmp(reject_ptr->name2, list_ptr->name2)) {
12538 				xodtemplate_remove_memberlist_item(list_ptr, &temp_list);
12539 				break;
12540 				}
12541 			}
12542 		}
12543 	xodtemplate_free_memberlist(&reject_list);
12544 	reject_list = NULL;
12545 
12546 	return temp_list;
12547 	}
12548 
12549 
12550 /* expands servicegroups */
xodtemplate_expand_servicegroups(xodtemplate_memberlist ** list,xodtemplate_memberlist ** reject_list,char * servicegroups,int _config_file,int _start_line)12551 int xodtemplate_expand_servicegroups(xodtemplate_memberlist **list, xodtemplate_memberlist **reject_list, char *servicegroups, int _config_file, int _start_line) {
12552 	xodtemplate_servicegroup  *temp_servicegroup = NULL;
12553 	regex_t preg;
12554 	char *servicegroup_names = NULL;
12555 	char *temp_ptr = NULL;
12556 	int found_match = TRUE;
12557 	int reject_item = FALSE;
12558 	int use_regexp = FALSE;
12559 
12560 	if(list == NULL)
12561 		return ERROR;
12562 	if(servicegroups == NULL)
12563 		return OK;
12564 
12565 	/* allocate memory for servicegroup name list */
12566 	if((servicegroup_names = (char *)strdup(servicegroups)) == NULL)
12567 		return ERROR;
12568 
12569 	/* expand each servicegroup */
12570 	for(temp_ptr = strtok(servicegroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) {
12571 
12572 		found_match = FALSE;
12573 		reject_item = FALSE;
12574 
12575 		/* strip trailing spaces */
12576 		strip(temp_ptr);
12577 
12578 		/* should we use regular expression matching? */
12579 		if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\.")))
12580 			use_regexp = TRUE;
12581 		else
12582 			use_regexp = FALSE;
12583 
12584 		/* use regular expression matching */
12585 		if(use_regexp == TRUE) {
12586 
12587 			/* compile regular expression */
12588 			if(regcomp(&preg, temp_ptr, REG_EXTENDED)) {
12589 				my_free(servicegroup_names);
12590 				return ERROR;
12591 				}
12592 
12593 			/* test match against all servicegroup names */
12594 			for(temp_servicegroup = xodtemplate_servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) {
12595 
12596 				if(temp_servicegroup->servicegroup_name == NULL)
12597 					continue;
12598 
12599 				/* skip this servicegroup if it did not match the expression */
12600 				if(regexec(&preg, temp_servicegroup->servicegroup_name, 0, NULL, 0))
12601 					continue;
12602 
12603 				found_match = TRUE;
12604 
12605 				/* dont' add servicegroups that shouldn't be registered */
12606 				if(temp_servicegroup->register_object == FALSE)
12607 					continue;
12608 
12609 				/* add servicegroup members to list */
12610 				xodtemplate_add_servicegroup_members_to_memberlist(list, temp_servicegroup, _config_file, _start_line);
12611 				}
12612 
12613 			/* free memory allocated to compiled regexp */
12614 			regfree(&preg);
12615 			}
12616 
12617 		/* use standard matching... */
12618 		else {
12619 
12620 			/* return a list of all servicegroups */
12621 			if(!strcmp(temp_ptr, "*")) {
12622 
12623 				found_match = TRUE;
12624 
12625 				for(temp_servicegroup = xodtemplate_servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) {
12626 
12627 					/* dont' add servicegroups that shouldn't be registered */
12628 					if(temp_servicegroup->register_object == FALSE)
12629 						continue;
12630 
12631 					/* add servicegroup to list */
12632 					xodtemplate_add_servicegroup_members_to_memberlist(list, temp_servicegroup, _config_file, _start_line);
12633 					}
12634 				}
12635 
12636 			/* else this is just a single servicegroup... */
12637 			else {
12638 
12639 				/* this servicegroup should be excluded (rejected) */
12640 				if(temp_ptr[0] == '!') {
12641 					reject_item = TRUE;
12642 					temp_ptr++;
12643 					}
12644 
12645 				/* find the servicegroup */
12646 				if((temp_servicegroup = xodtemplate_find_real_servicegroup(temp_ptr)) != NULL) {
12647 
12648 					found_match = TRUE;
12649 
12650 					/* add servicegroup members to list */
12651 					xodtemplate_add_servicegroup_members_to_memberlist((reject_item == TRUE) ? reject_list : list, temp_servicegroup, _config_file, _start_line);
12652 					}
12653 				}
12654 			}
12655 
12656 		/* we didn't find a matching servicegroup */
12657 		if(found_match == FALSE) {
12658 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find any servicegroup matching '%s' (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(_config_file), _start_line);
12659 			break;
12660 			}
12661 		}
12662 
12663 	/* free memory */
12664 	my_free(servicegroup_names);
12665 
12666 	if(found_match == FALSE)
12667 		return ERROR;
12668 
12669 	return OK;
12670 	}
12671 
12672 
12673 /* expands services (host name is not expanded) */
xodtemplate_expand_services(xodtemplate_memberlist ** list,xodtemplate_memberlist ** reject_list,char * host_name,char * services,int _config_file,int _start_line)12674 int xodtemplate_expand_services(xodtemplate_memberlist **list, xodtemplate_memberlist **reject_list, char *host_name, char *services, int _config_file, int _start_line) {
12675 	char *service_names = NULL;
12676 	char *temp_ptr = NULL;
12677 	xodtemplate_service *temp_service = NULL;
12678 	regex_t preg;
12679 	regex_t preg2;
12680 	int found_match = TRUE;
12681 	int reject_item = FALSE;
12682 	int use_regexp_host = FALSE;
12683 	int use_regexp_service = FALSE;
12684 
12685 	if(list == NULL)
12686 		return ERROR;
12687 	if(host_name == NULL || services == NULL)
12688 		return OK;
12689 
12690 	/* should we use regular expression matching for the host name? */
12691 	if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(host_name, "*") || strstr(host_name, "?") || strstr(host_name, "+") || strstr(host_name, "\\.")))
12692 		use_regexp_host = TRUE;
12693 
12694 	/* compile regular expression for host name */
12695 	if(use_regexp_host == TRUE) {
12696 		if(regcomp(&preg2, host_name, REG_EXTENDED))
12697 			return ERROR;
12698 		}
12699 
12700 	if((service_names = (char *)strdup(services)) == NULL) {
12701 		if(use_regexp_host == TRUE)
12702 			regfree(&preg2);
12703 		return ERROR;
12704 		}
12705 
12706 	/* expand each service description */
12707 	for(temp_ptr = strtok(service_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) {
12708 
12709 		found_match = FALSE;
12710 		reject_item = FALSE;
12711 
12712 		/* strip trailing spaces */
12713 		strip(temp_ptr);
12714 
12715 		/* should we use regular expression matching for the service description? */
12716 		if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\.")))
12717 			use_regexp_service = TRUE;
12718 		else
12719 			use_regexp_service = FALSE;
12720 
12721 		/* compile regular expression for service description */
12722 		if(use_regexp_service == TRUE) {
12723 			if(regcomp(&preg, temp_ptr, REG_EXTENDED)) {
12724 				if(use_regexp_host == TRUE)
12725 					regfree(&preg2);
12726 				my_free(service_names);
12727 				return ERROR;
12728 				}
12729 			}
12730 
12731 		/* use regular expression matching */
12732 		if(use_regexp_host == TRUE || use_regexp_service == TRUE) {
12733 
12734 			/* test match against all services */
12735 			for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) {
12736 
12737 				if(temp_service->host_name == NULL || temp_service->service_description == NULL)
12738 					continue;
12739 
12740 				/* skip this service if it doesn't match the host name expression */
12741 				if(use_regexp_host == TRUE) {
12742 					if(regexec(&preg2, temp_service->host_name, 0, NULL, 0))
12743 						continue;
12744 					}
12745 				else {
12746 					if(strcmp(temp_service->host_name, host_name))
12747 						continue;
12748 					}
12749 
12750 				/* skip this service if it doesn't match the service description expression */
12751 				if(use_regexp_service == TRUE) {
12752 					if(regexec(&preg, temp_service->service_description, 0, NULL, 0))
12753 						continue;
12754 					}
12755 				else {
12756 					if(strcmp(temp_service->service_description, temp_ptr))
12757 						continue;
12758 					}
12759 
12760 				found_match = TRUE;
12761 
12762 				/* dont' add services that shouldn't be registered */
12763 				if(temp_service->register_object == FALSE)
12764 					continue;
12765 
12766 				/* add service to the list */
12767 				xodtemplate_add_member_to_memberlist(list, host_name, temp_service->service_description);
12768 				}
12769 
12770 			/* free memory allocated to compiled regexp */
12771 			if(use_regexp_service == TRUE)
12772 				regfree(&preg);
12773 			}
12774 
12775 		/* use standard matching... */
12776 		else {
12777 
12778 			/* return a list of all services on the host */
12779 			if(!strcmp(temp_ptr, "*")) {
12780 
12781 				found_match = TRUE;
12782 
12783 				for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) {
12784 
12785 					if(temp_service->host_name == NULL || temp_service->service_description == NULL)
12786 						continue;
12787 
12788 					if(strcmp(temp_service->host_name, host_name))
12789 						continue;
12790 
12791 					/* dont' add services that shouldn't be registered */
12792 					if(temp_service->register_object == FALSE)
12793 						continue;
12794 
12795 					/* add service to the list */
12796 					xodtemplate_add_member_to_memberlist(list, host_name, temp_service->service_description);
12797 					}
12798 				}
12799 
12800 			/* else this is just a single service... */
12801 			else {
12802 
12803 				/* this service should be excluded (rejected) */
12804 				if(temp_ptr[0] == '!') {
12805 					reject_item = TRUE;
12806 					temp_ptr++;
12807 					}
12808 
12809 				/* find the service */
12810 				if((temp_service = xodtemplate_find_real_service(host_name, temp_ptr)) != NULL) {
12811 
12812 					found_match = TRUE;
12813 
12814 					/* add service to the list */
12815 					xodtemplate_add_member_to_memberlist((reject_item == TRUE) ? reject_list : list, host_name, temp_service->service_description);
12816 					}
12817 				}
12818 			}
12819 
12820 		/* we didn't find a match */
12821 		if(found_match == FALSE && reject_item == FALSE) {
12822 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find a service matching host name '%s' and description '%s' (config file '%s', starting on line %d)\n", host_name, temp_ptr, xodtemplate_config_file_name(_config_file), _start_line);
12823 			break;
12824 			}
12825 		}
12826 
12827 	if(use_regexp_host == TRUE)
12828 		regfree(&preg2);
12829 	my_free(service_names);
12830 
12831 	if(found_match == FALSE && reject_item == FALSE)
12832 		return ERROR;
12833 
12834 	return OK;
12835 	}
12836 
12837 
12838 /* adds members of a servicegroups to the list of expanded services */
xodtemplate_add_servicegroup_members_to_memberlist(xodtemplate_memberlist ** list,xodtemplate_servicegroup * temp_servicegroup,int _config_file,int _start_line)12839 int xodtemplate_add_servicegroup_members_to_memberlist(xodtemplate_memberlist **list, xodtemplate_servicegroup *temp_servicegroup, int _config_file, int _start_line) {
12840 	char *group_members = NULL;
12841 	char *member_name = NULL;
12842 	char *host_name = NULL;
12843 	char *member_ptr = NULL;
12844 
12845 	if(list == NULL || temp_servicegroup == NULL)
12846 		return ERROR;
12847 
12848 	/* if we have no members, just return. Empty servicegroups are ok */
12849 	if(temp_servicegroup->members == NULL) {
12850 		return OK;
12851 		}
12852 
12853 	/* save a copy of the members */
12854 	if((group_members = (char *)strdup(temp_servicegroup->members)) == NULL)
12855 		return ERROR;
12856 
12857 	/* process all services that belong to the servicegroup */
12858 	/* NOTE: members of the group have already have been expanded by xodtemplate_recombobulate_servicegroups(), so we don't need to do it here */
12859 	member_ptr = group_members;
12860 	for(member_name = my_strsep(&member_ptr, ","); member_name != NULL; member_name = my_strsep(&member_ptr, ",")) {
12861 
12862 		/* strip trailing spaces from member name */
12863 		strip(member_name);
12864 
12865 		/* host name */
12866 		if(host_name == NULL) {
12867 			if((host_name = (char *)strdup(member_name)) == NULL) {
12868 				my_free(group_members);
12869 				return ERROR;
12870 				}
12871 			}
12872 
12873 		/* service description */
12874 		else {
12875 
12876 			/* add service to the list */
12877 			xodtemplate_add_member_to_memberlist(list, host_name, member_name);
12878 
12879 			my_free(host_name);
12880 			}
12881 		}
12882 
12883 	my_free(group_members);
12884 
12885 	return OK;
12886 	}
12887 
12888 
12889 
12890 
12891 /* returns a comma-delimited list of hostgroup names */
xodtemplate_process_hostgroup_names(char * hostgroups,int _config_file,int _start_line)12892 char * xodtemplate_process_hostgroup_names(char *hostgroups, int _config_file, int _start_line) {
12893 	xodtemplate_memberlist *temp_list = NULL;
12894 	xodtemplate_memberlist *reject_list = NULL;
12895 	xodtemplate_memberlist *list_ptr = NULL;
12896 	xodtemplate_memberlist *reject_ptr = NULL;
12897 	xodtemplate_memberlist *this_list = NULL;
12898 	char *buf = NULL;
12899 	int result = OK;
12900 
12901 	/* process list of hostgroups... */
12902 	if(hostgroups != NULL) {
12903 
12904 		/* split group names into two lists */
12905 		result = xodtemplate_get_hostgroup_names(&temp_list, &reject_list, hostgroups, _config_file, _start_line);
12906 		if(result != OK) {
12907 			xodtemplate_free_memberlist(&temp_list);
12908 			xodtemplate_free_memberlist(&reject_list);
12909 			return NULL;
12910 			}
12911 
12912 		/* remove rejects (if any) from the list (no duplicate entries exist in either list) */
12913 		for(reject_ptr = reject_list; reject_ptr != NULL; reject_ptr = reject_ptr->next) {
12914 			for(list_ptr = temp_list; list_ptr != NULL; list_ptr = list_ptr->next) {
12915 				if(!strcmp(reject_ptr->name1, list_ptr->name1)) {
12916 					xodtemplate_remove_memberlist_item(list_ptr, &temp_list);
12917 					break;
12918 					}
12919 				}
12920 			}
12921 
12922 		xodtemplate_free_memberlist(&reject_list);
12923 		reject_list = NULL;
12924 		}
12925 
12926 	/* generate the list of group members */
12927 	for(this_list = temp_list; this_list != NULL; this_list = this_list->next) {
12928 		if(buf == NULL) {
12929 			buf = (char *)malloc(strlen(this_list->name1) + 1);
12930 			strcpy(buf, this_list->name1);
12931 			}
12932 		else {
12933 			buf = (char *)realloc(buf, strlen(buf) + strlen(this_list->name1) + 2);
12934 			strcat(buf, ",");
12935 			strcat(buf, this_list->name1);
12936 			}
12937 		}
12938 
12939 	xodtemplate_free_memberlist(&temp_list);
12940 
12941 	return buf;
12942 	}
12943 
12944 
12945 
12946 /* return a list of hostgroup names */
xodtemplate_get_hostgroup_names(xodtemplate_memberlist ** list,xodtemplate_memberlist ** reject_list,char * hostgroups,int _config_file,int _start_line)12947 int xodtemplate_get_hostgroup_names(xodtemplate_memberlist **list, xodtemplate_memberlist **reject_list, char *hostgroups, int _config_file, int _start_line) {
12948 	char *hostgroup_names = NULL;
12949 	char *temp_ptr = NULL;
12950 	xodtemplate_hostgroup *temp_hostgroup = NULL;
12951 	regex_t preg;
12952 	int found_match = TRUE;
12953 	int reject_item = FALSE;
12954 	int use_regexp = FALSE;
12955 
12956 	if(list == NULL || hostgroups == NULL)
12957 		return ERROR;
12958 
12959 	/* allocate memory for hostgroup name list */
12960 	if((hostgroup_names = (char *)strdup(hostgroups)) == NULL)
12961 		return ERROR;
12962 
12963 	for(temp_ptr = strtok(hostgroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) {
12964 
12965 		found_match = FALSE;
12966 		reject_item = FALSE;
12967 
12968 		/* strip trailing spaces */
12969 		strip(temp_ptr);
12970 
12971 		/* should we use regular expression matching? */
12972 		if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\.")))
12973 			use_regexp = TRUE;
12974 		else
12975 			use_regexp = FALSE;
12976 
12977 		/* use regular expression matching */
12978 		if(use_regexp == TRUE) {
12979 
12980 			/* compile regular expression */
12981 			if(regcomp(&preg, temp_ptr, REG_EXTENDED)) {
12982 				my_free(hostgroup_names);
12983 				return ERROR;
12984 				}
12985 
12986 			/* test match against all hostgroup names */
12987 			for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) {
12988 
12989 				if(temp_hostgroup->hostgroup_name == NULL)
12990 					continue;
12991 
12992 				/* skip this hostgroup if it did not match the expression */
12993 				if(regexec(&preg, temp_hostgroup->hostgroup_name, 0, NULL, 0))
12994 					continue;
12995 
12996 				found_match = TRUE;
12997 
12998 				/* dont' add hostgroups that shouldn't be registered */
12999 				if(temp_hostgroup->register_object == FALSE)
13000 					continue;
13001 
13002 				/* add hostgroup to list */
13003 				xodtemplate_add_member_to_memberlist(list, temp_hostgroup->hostgroup_name, NULL);
13004 				}
13005 
13006 			/* free memory allocated to compiled regexp */
13007 			regfree(&preg);
13008 			}
13009 
13010 		/* use standard matching... */
13011 		else {
13012 
13013 			/* return a list of all hostgroups */
13014 			if(!strcmp(temp_ptr, "*")) {
13015 
13016 				found_match = TRUE;
13017 
13018 				for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) {
13019 
13020 					/* dont' add hostgroups that shouldn't be registered */
13021 					if(temp_hostgroup->register_object == FALSE)
13022 						continue;
13023 
13024 					/* add hostgroup to list */
13025 					xodtemplate_add_member_to_memberlist(list, temp_hostgroup->hostgroup_name, NULL);
13026 					}
13027 				}
13028 
13029 			/* else this is just a single hostgroup... */
13030 			else {
13031 
13032 				/* this hostgroup should be excluded (rejected) */
13033 				if(temp_ptr[0] == '!') {
13034 					reject_item = TRUE;
13035 					temp_ptr++;
13036 					}
13037 
13038 				/* find the hostgroup */
13039 				temp_hostgroup = xodtemplate_find_real_hostgroup(temp_ptr);
13040 				if(temp_hostgroup != NULL) {
13041 
13042 					found_match = TRUE;
13043 
13044 					/* add hostgroup members to proper list */
13045 					xodtemplate_add_member_to_memberlist((reject_item == TRUE) ? reject_list : list, temp_hostgroup->hostgroup_name, NULL);
13046 					}
13047 				}
13048 			}
13049 
13050 		if(found_match == FALSE) {
13051 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find any hostgroup matching '%s' (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(_config_file), _start_line);
13052 			break;
13053 			}
13054 		}
13055 
13056 	/* free memory */
13057 	my_free(hostgroup_names);
13058 
13059 	if(found_match == FALSE)
13060 		return ERROR;
13061 
13062 	return OK;
13063 	}
13064 
13065 
13066 
13067 /* returns a comma-delimited list of contactgroup names */
xodtemplate_process_contactgroup_names(char * contactgroups,int _config_file,int _start_line)13068 char * xodtemplate_process_contactgroup_names(char *contactgroups, int _config_file, int _start_line) {
13069 	xodtemplate_memberlist *temp_list = NULL;
13070 	xodtemplate_memberlist *reject_list = NULL;
13071 	xodtemplate_memberlist *list_ptr = NULL;
13072 	xodtemplate_memberlist *reject_ptr = NULL;
13073 	xodtemplate_memberlist *this_list = NULL;
13074 	char *buf = NULL;
13075 	int result = OK;
13076 
13077 	/* process list of contactgroups... */
13078 	if(contactgroups != NULL) {
13079 
13080 		/* split group names into two lists */
13081 		result = xodtemplate_get_contactgroup_names(&temp_list, &reject_list, contactgroups, _config_file, _start_line);
13082 		if(result != OK) {
13083 			xodtemplate_free_memberlist(&temp_list);
13084 			xodtemplate_free_memberlist(&reject_list);
13085 			return NULL;
13086 			}
13087 
13088 		/* remove rejects (if any) from the list (no duplicate entries exist in either list) */
13089 		for(reject_ptr = reject_list; reject_ptr != NULL; reject_ptr = reject_ptr->next) {
13090 			for(list_ptr = temp_list; list_ptr != NULL; list_ptr = list_ptr->next) {
13091 				if(!strcmp(reject_ptr->name1, list_ptr->name1)) {
13092 					xodtemplate_remove_memberlist_item(list_ptr, &temp_list);
13093 					break;
13094 					}
13095 				}
13096 			}
13097 
13098 		xodtemplate_free_memberlist(&reject_list);
13099 		reject_list = NULL;
13100 		}
13101 
13102 	/* generate the list of group members */
13103 	for(this_list = temp_list; this_list != NULL; this_list = this_list->next) {
13104 		if(buf == NULL) {
13105 			buf = (char *)malloc(strlen(this_list->name1) + 1);
13106 			strcpy(buf, this_list->name1);
13107 			}
13108 		else {
13109 			buf = (char *)realloc(buf, strlen(buf) + strlen(this_list->name1) + 2);
13110 			strcat(buf, ",");
13111 			strcat(buf, this_list->name1);
13112 			}
13113 		}
13114 
13115 	xodtemplate_free_memberlist(&temp_list);
13116 
13117 	return buf;
13118 	}
13119 
13120 
13121 
13122 /* return a list of contactgroup names */
xodtemplate_get_contactgroup_names(xodtemplate_memberlist ** list,xodtemplate_memberlist ** reject_list,char * contactgroups,int _config_file,int _start_line)13123 int xodtemplate_get_contactgroup_names(xodtemplate_memberlist **list, xodtemplate_memberlist **reject_list, char *contactgroups, int _config_file, int _start_line) {
13124 	char *contactgroup_names = NULL;
13125 	char *temp_ptr = NULL;
13126 	xodtemplate_contactgroup *temp_contactgroup = NULL;
13127 	regex_t preg;
13128 	int found_match = TRUE;
13129 	int reject_item = FALSE;
13130 	int use_regexp = FALSE;
13131 
13132 	if(list == NULL || contactgroups == NULL)
13133 		return ERROR;
13134 
13135 	/* allocate memory for contactgroup name list */
13136 	if((contactgroup_names = (char *)strdup(contactgroups)) == NULL)
13137 		return ERROR;
13138 
13139 	for(temp_ptr = strtok(contactgroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) {
13140 
13141 		found_match = FALSE;
13142 		reject_item = FALSE;
13143 
13144 		/* strip trailing spaces */
13145 		strip(temp_ptr);
13146 
13147 		/* should we use regular expression matching? */
13148 		if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\.")))
13149 			use_regexp = TRUE;
13150 		else
13151 			use_regexp = FALSE;
13152 
13153 		/* use regular expression matching */
13154 		if(use_regexp == TRUE) {
13155 
13156 			/* compile regular expression */
13157 			if(regcomp(&preg, temp_ptr, REG_EXTENDED)) {
13158 				my_free(contactgroup_names);
13159 				return ERROR;
13160 				}
13161 
13162 			/* test match against all contactgroup names */
13163 			for(temp_contactgroup = xodtemplate_contactgroup_list; temp_contactgroup != NULL; temp_contactgroup = temp_contactgroup->next) {
13164 
13165 				if(temp_contactgroup->contactgroup_name == NULL)
13166 					continue;
13167 
13168 				/* skip this contactgroup if it did not match the expression */
13169 				if(regexec(&preg, temp_contactgroup->contactgroup_name, 0, NULL, 0))
13170 					continue;
13171 
13172 				found_match = TRUE;
13173 
13174 				/* dont' add contactgroups that shouldn't be registered */
13175 				if(temp_contactgroup->register_object == FALSE)
13176 					continue;
13177 
13178 				/* add contactgroup to list */
13179 				xodtemplate_add_member_to_memberlist(list, temp_contactgroup->contactgroup_name, NULL);
13180 				}
13181 
13182 			/* free memory allocated to compiled regexp */
13183 			regfree(&preg);
13184 			}
13185 
13186 		/* use standard matching... */
13187 		else {
13188 
13189 			/* return a list of all contactgroups */
13190 			if(!strcmp(temp_ptr, "*")) {
13191 
13192 				found_match = TRUE;
13193 
13194 				for(temp_contactgroup = xodtemplate_contactgroup_list; temp_contactgroup != NULL; temp_contactgroup = temp_contactgroup->next) {
13195 
13196 					/* dont' add contactgroups that shouldn't be registered */
13197 					if(temp_contactgroup->register_object == FALSE)
13198 						continue;
13199 
13200 					/* add contactgroup to list */
13201 					xodtemplate_add_member_to_memberlist(list, temp_contactgroup->contactgroup_name, NULL);
13202 					}
13203 				}
13204 
13205 			/* else this is just a single contactgroup... */
13206 			else {
13207 
13208 				/* this contactgroup should be excluded (rejected) */
13209 				if(temp_ptr[0] == '!') {
13210 					reject_item = TRUE;
13211 					temp_ptr++;
13212 					}
13213 
13214 				/* find the contactgroup */
13215 				temp_contactgroup = xodtemplate_find_real_contactgroup(temp_ptr);
13216 				if(temp_contactgroup != NULL) {
13217 
13218 					found_match = TRUE;
13219 
13220 					/* add contactgroup members to proper list */
13221 					xodtemplate_add_member_to_memberlist((reject_item == TRUE) ? reject_list : list, temp_contactgroup->contactgroup_name, NULL);
13222 					}
13223 				}
13224 			}
13225 
13226 		if(found_match == FALSE) {
13227 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find any contactgroup matching '%s' (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(_config_file), _start_line);
13228 			break;
13229 			}
13230 		}
13231 
13232 	/* free memory */
13233 	my_free(contactgroup_names);
13234 
13235 	if(found_match == FALSE)
13236 		return ERROR;
13237 
13238 	return OK;
13239 	}
13240 
13241 
13242 
13243 /* returns a comma-delimited list of servicegroup names */
xodtemplate_process_servicegroup_names(char * servicegroups,int _config_file,int _start_line)13244 char * xodtemplate_process_servicegroup_names(char *servicegroups, int _config_file, int _start_line) {
13245 	xodtemplate_memberlist *temp_list = NULL;
13246 	xodtemplate_memberlist *reject_list = NULL;
13247 	xodtemplate_memberlist *list_ptr = NULL;
13248 	xodtemplate_memberlist *reject_ptr = NULL;
13249 	xodtemplate_memberlist *this_list = NULL;
13250 	char *buf = NULL;
13251 	int result = OK;
13252 
13253 	/* process list of servicegroups... */
13254 	if(servicegroups != NULL) {
13255 
13256 		/* split group names into two lists */
13257 		result = xodtemplate_get_servicegroup_names(&temp_list, &reject_list, servicegroups, _config_file, _start_line);
13258 		if(result != OK) {
13259 			xodtemplate_free_memberlist(&temp_list);
13260 			xodtemplate_free_memberlist(&reject_list);
13261 			return NULL;
13262 			}
13263 
13264 		/* remove rejects (if any) from the list (no duplicate entries exist in either list) */
13265 		for(reject_ptr = reject_list; reject_ptr != NULL; reject_ptr = reject_ptr->next) {
13266 			for(list_ptr = temp_list; list_ptr != NULL; list_ptr = list_ptr->next) {
13267 				if(!strcmp(reject_ptr->name1, list_ptr->name1)) {
13268 					xodtemplate_remove_memberlist_item(list_ptr, &temp_list);
13269 					break;
13270 					}
13271 				}
13272 			}
13273 
13274 		xodtemplate_free_memberlist(&reject_list);
13275 		reject_list = NULL;
13276 		}
13277 
13278 	/* generate the list of group members */
13279 	for(this_list = temp_list; this_list != NULL; this_list = this_list->next) {
13280 		if(buf == NULL) {
13281 			buf = (char *)malloc(strlen(this_list->name1) + 1);
13282 			strcpy(buf, this_list->name1);
13283 			}
13284 		else {
13285 			buf = (char *)realloc(buf, strlen(buf) + strlen(this_list->name1) + 2);
13286 			strcat(buf, ",");
13287 			strcat(buf, this_list->name1);
13288 			}
13289 		}
13290 
13291 	xodtemplate_free_memberlist(&temp_list);
13292 
13293 	return buf;
13294 	}
13295 
13296 
13297 
13298 /* return a list of servicegroup names */
xodtemplate_get_servicegroup_names(xodtemplate_memberlist ** list,xodtemplate_memberlist ** reject_list,char * servicegroups,int _config_file,int _start_line)13299 int xodtemplate_get_servicegroup_names(xodtemplate_memberlist **list, xodtemplate_memberlist **reject_list, char *servicegroups, int _config_file, int _start_line) {
13300 	char *servicegroup_names = NULL;
13301 	char *temp_ptr = NULL;
13302 	xodtemplate_servicegroup *temp_servicegroup = NULL;
13303 	regex_t preg;
13304 	int found_match = TRUE;
13305 	int reject_item = FALSE;
13306 	int use_regexp = FALSE;
13307 
13308 	if(list == NULL || servicegroups == NULL)
13309 		return ERROR;
13310 
13311 	/* allocate memory for servicegroup name list */
13312 	if((servicegroup_names = (char *)strdup(servicegroups)) == NULL)
13313 		return ERROR;
13314 
13315 	for(temp_ptr = strtok(servicegroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) {
13316 
13317 		found_match = FALSE;
13318 		reject_item = FALSE;
13319 
13320 		/* strip trailing spaces */
13321 		strip(temp_ptr);
13322 
13323 		/* should we use regular expression matching? */
13324 		if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\.")))
13325 			use_regexp = TRUE;
13326 		else
13327 			use_regexp = FALSE;
13328 
13329 		/* use regular expression matching */
13330 		if(use_regexp == TRUE) {
13331 
13332 			/* compile regular expression */
13333 			if(regcomp(&preg, temp_ptr, REG_EXTENDED)) {
13334 				my_free(servicegroup_names);
13335 				return ERROR;
13336 				}
13337 
13338 			/* test match against all servicegroup names */
13339 			for(temp_servicegroup = xodtemplate_servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) {
13340 
13341 				if(temp_servicegroup->servicegroup_name == NULL)
13342 					continue;
13343 
13344 				/* skip this servicegroup if it did not match the expression */
13345 				if(regexec(&preg, temp_servicegroup->servicegroup_name, 0, NULL, 0))
13346 					continue;
13347 
13348 				found_match = TRUE;
13349 
13350 				/* dont' add servicegroups that shouldn't be registered */
13351 				if(temp_servicegroup->register_object == FALSE)
13352 					continue;
13353 
13354 				/* add servicegroup to list */
13355 				xodtemplate_add_member_to_memberlist(list, temp_servicegroup->servicegroup_name, NULL);
13356 				}
13357 
13358 			/* free memory allocated to compiled regexp */
13359 			regfree(&preg);
13360 			}
13361 
13362 		/* use standard matching... */
13363 		else {
13364 
13365 			/* return a list of all servicegroups */
13366 			if(!strcmp(temp_ptr, "*")) {
13367 
13368 				found_match = TRUE;
13369 
13370 				for(temp_servicegroup = xodtemplate_servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) {
13371 
13372 					/* dont' add servicegroups that shouldn't be registered */
13373 					if(temp_servicegroup->register_object == FALSE)
13374 						continue;
13375 
13376 					/* add servicegroup to list */
13377 					xodtemplate_add_member_to_memberlist(list, temp_servicegroup->servicegroup_name, NULL);
13378 					}
13379 				}
13380 
13381 			/* else this is just a single servicegroup... */
13382 			else {
13383 
13384 				/* this servicegroup should be excluded (rejected) */
13385 				if(temp_ptr[0] == '!') {
13386 					reject_item = TRUE;
13387 					temp_ptr++;
13388 					}
13389 
13390 				/* find the servicegroup */
13391 				temp_servicegroup = xodtemplate_find_real_servicegroup(temp_ptr);
13392 				if(temp_servicegroup != NULL) {
13393 
13394 					found_match = TRUE;
13395 
13396 					/* add servicegroup members to proper list */
13397 					xodtemplate_add_member_to_memberlist((reject_item == TRUE) ? reject_list : list, temp_servicegroup->servicegroup_name, NULL);
13398 					}
13399 				}
13400 			}
13401 
13402 		if(found_match == FALSE) {
13403 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find any servicegroup matching '%s' (config file '%s', starting on line %d)\n", temp_ptr, xodtemplate_config_file_name(_config_file), _start_line);
13404 			break;
13405 			}
13406 		}
13407 
13408 	/* free memory */
13409 	my_free(servicegroup_names);
13410 
13411 	if(found_match == FALSE)
13412 		return ERROR;
13413 
13414 	return OK;
13415 	}
13416 
13417 #ifdef NSCORE
13418 
13419 /******************************************************************/
13420 /****************** ADDITIVE INHERITANCE STUFF ********************/
13421 /******************************************************************/
13422 
13423 /* determines the value of an inherited string */
xodtemplate_get_inherited_string(int * have_template_value,char ** template_value,int * have_this_value,char ** this_value)13424 int xodtemplate_get_inherited_string(int *have_template_value, char **template_value, int *have_this_value, char **this_value) {
13425 	char *buf = NULL;
13426 
13427 	/* template has a value we should use */
13428 	if(*have_template_value == TRUE) {
13429 
13430 		/* template has a non-NULL value */
13431 		if(*template_value != NULL) {
13432 
13433 			/* we have no value... */
13434 			if(*this_value == NULL) {
13435 
13436 				/* use the template value only if we need a value - otherwise stay NULL */
13437 				if(*have_this_value == FALSE) {
13438 					/* NOTE: leave leading + sign if present, as it needed during object resolution and will get stripped later */
13439 					*this_value = (char *)strdup(*template_value);
13440 					}
13441 				}
13442 
13443 			/* we already have a value... */
13444 			else {
13445 				/* our value should be added to the template value */
13446 				if(*this_value[0] == '+') {
13447 					if((buf = (char *)malloc(strlen(*template_value) + strlen(*this_value) + 1))) {
13448 						strcpy(buf, *template_value);
13449 						strcat(buf, ",");
13450 						strcat(buf, *this_value + 1);
13451 						my_free(*this_value);
13452 						*this_value = buf;
13453 						}
13454 					}
13455 
13456 				/* otherwise our value overrides/replaces the template value */
13457 				}
13458 			}
13459 
13460 		/* template has a NULL value.... */
13461 
13462 		*have_this_value = TRUE;
13463 		}
13464 
13465 	return OK;
13466 	}
13467 
13468 
13469 /* removes leading + sign from various directives */
xodtemplate_clean_additive_string(char ** str)13470 int xodtemplate_clean_additive_string(char **str) {
13471 	char *buf = NULL;
13472 
13473 	/* remove the additive symbol if present */
13474 	if(*str != NULL && *str[0] == '+') {
13475 		buf = (char *)strdup(*str + 1);
13476 		my_free(*str);
13477 		*str = buf;
13478 		}
13479 
13480 	return OK;
13481 	}
13482 
13483 
13484 /* cleans strings which may contain additive inheritance directives */
13485 /* NOTE: this must be done after objects are resolved */
xodtemplate_clean_additive_strings(void)13486 int xodtemplate_clean_additive_strings(void) {
13487 	xodtemplate_contactgroup *temp_contactgroup = NULL;
13488 	xodtemplate_hostgroup *temp_hostgroup = NULL;
13489 	xodtemplate_servicegroup *temp_servicegroup = NULL;
13490 	xodtemplate_servicedependency *temp_servicedependency = NULL;
13491 	xodtemplate_serviceescalation *temp_serviceescalation = NULL;
13492 	xodtemplate_contact *temp_contact = NULL;
13493 	xodtemplate_host *temp_host = NULL;
13494 	xodtemplate_service *temp_service = NULL;
13495 	xodtemplate_hostdependency *temp_hostdependency = NULL;
13496 	xodtemplate_hostescalation *temp_hostescalation = NULL;
13497 
13498 	/* resolve all contactgroup objects */
13499 	for(temp_contactgroup = xodtemplate_contactgroup_list; temp_contactgroup != NULL; temp_contactgroup = temp_contactgroup->next) {
13500 		xodtemplate_clean_additive_string(&temp_contactgroup->members);
13501 		xodtemplate_clean_additive_string(&temp_contactgroup->contactgroup_members);
13502 		}
13503 
13504 	/* resolve all hostgroup objects */
13505 	for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) {
13506 		xodtemplate_clean_additive_string(&temp_hostgroup->members);
13507 		xodtemplate_clean_additive_string(&temp_hostgroup->hostgroup_members);
13508 		}
13509 
13510 	/* resolve all servicegroup objects */
13511 	for(temp_servicegroup = xodtemplate_servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) {
13512 		xodtemplate_clean_additive_string(&temp_servicegroup->members);
13513 		xodtemplate_clean_additive_string(&temp_servicegroup->servicegroup_members);
13514 		}
13515 
13516 	/* resolve all servicedependency objects */
13517 	for(temp_servicedependency = xodtemplate_servicedependency_list; temp_servicedependency != NULL; temp_servicedependency = temp_servicedependency->next) {
13518 		xodtemplate_clean_additive_string(&temp_servicedependency->servicegroup_name);
13519 		xodtemplate_clean_additive_string(&temp_servicedependency->hostgroup_name);
13520 		xodtemplate_clean_additive_string(&temp_servicedependency->host_name);
13521 		xodtemplate_clean_additive_string(&temp_servicedependency->service_description);
13522 		xodtemplate_clean_additive_string(&temp_servicedependency->dependent_servicegroup_name);
13523 		xodtemplate_clean_additive_string(&temp_servicedependency->dependent_hostgroup_name);
13524 		xodtemplate_clean_additive_string(&temp_servicedependency->dependent_host_name);
13525 		xodtemplate_clean_additive_string(&temp_servicedependency->dependent_service_description);
13526 		}
13527 
13528 	/* resolve all serviceescalation objects */
13529 	for(temp_serviceescalation = xodtemplate_serviceescalation_list; temp_serviceescalation != NULL; temp_serviceescalation = temp_serviceescalation->next) {
13530 		/* 03/05/08 some vars are now handled in xodtemplate_inherit_object_properties() */
13531 		/*
13532 		xodtemplate_clean_additive_string(&temp_serviceescalation->contact_groups);
13533 		xodtemplate_clean_additive_string(&temp_serviceescalation->contacts);
13534 		*/
13535 		xodtemplate_clean_additive_string(&temp_serviceescalation->servicegroup_name);
13536 		xodtemplate_clean_additive_string(&temp_serviceescalation->hostgroup_name);
13537 		xodtemplate_clean_additive_string(&temp_serviceescalation->host_name);
13538 		xodtemplate_clean_additive_string(&temp_serviceescalation->service_description);
13539 		}
13540 
13541 	/* resolve all contact objects */
13542 	for(temp_contact = xodtemplate_contact_list; temp_contact != NULL; temp_contact = temp_contact->next) {
13543 		xodtemplate_clean_additive_string(&temp_contact->contact_groups);
13544 		xodtemplate_clean_additive_string(&temp_contact->host_notification_commands);
13545 		xodtemplate_clean_additive_string(&temp_contact->service_notification_commands);
13546 		}
13547 
13548 	/* clean all host objects */
13549 	for(temp_host = xodtemplate_host_list; temp_host != NULL; temp_host = temp_host->next) {
13550 		xodtemplate_clean_additive_string(&temp_host->contact_groups);
13551 		xodtemplate_clean_additive_string(&temp_host->contacts);
13552 		xodtemplate_clean_additive_string(&temp_host->parents);
13553 		xodtemplate_clean_additive_string(&temp_host->host_groups);
13554 		}
13555 
13556 	/* clean all service objects */
13557 	for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) {
13558 		xodtemplate_clean_additive_string(&temp_service->contact_groups);
13559 		xodtemplate_clean_additive_string(&temp_service->contacts);
13560 		xodtemplate_clean_additive_string(&temp_service->host_name);
13561 		xodtemplate_clean_additive_string(&temp_service->hostgroup_name);
13562 		xodtemplate_clean_additive_string(&temp_service->service_groups);
13563 		}
13564 
13565 	/* resolve all hostdependency objects */
13566 	for(temp_hostdependency = xodtemplate_hostdependency_list; temp_hostdependency != NULL; temp_hostdependency = temp_hostdependency->next) {
13567 		xodtemplate_clean_additive_string(&temp_hostdependency->host_name);
13568 		xodtemplate_clean_additive_string(&temp_hostdependency->dependent_host_name);
13569 		xodtemplate_clean_additive_string(&temp_hostdependency->hostgroup_name);
13570 		xodtemplate_clean_additive_string(&temp_hostdependency->dependent_hostgroup_name);
13571 		}
13572 
13573 	/* resolve all hostescalation objects */
13574 	for(temp_hostescalation = xodtemplate_hostescalation_list; temp_hostescalation != NULL; temp_hostescalation = temp_hostescalation->next) {
13575 		/* 03/05/08 some vars are now handled in xodtemplate_inherit_object_properties() */
13576 		/*
13577 		xodtemplate_clean_additive_string(&temp_hostescalation->contact_groups);
13578 		xodtemplate_clean_additive_string(&temp_hostescalation->contacts);
13579 		*/
13580 		xodtemplate_clean_additive_string(&temp_hostescalation->host_name);
13581 		xodtemplate_clean_additive_string(&temp_hostescalation->hostgroup_name);
13582 		}
13583 
13584 	return OK;
13585 	}
13586 #endif
13587 
13588 #endif
13589 
13590 
13591