1 /*****************************************************************************
2  *
3  * XODTEMPLATE.C - Template-based object configuration data input routines
4  *
5  *
6  * Description:
7  *
8  * Routines for parsing and resolving template-based object definitions.
9  * Basic steps involved in this in the daemon are as follows:
10  *
11  *    1) Read
12  *    2) Resolve
13  *    3) Duplicate
14  *    4) Recombobulate
15  *    5) Cache
16  *    7) Register
17  *    8) Cleanup
18  *
19  * The steps involved for the CGIs differ a bit, since they read the cached
20  * definitions which are already resolved, recombobulated and duplicated.  In
21  * otherwords, they've already been "flattened"...
22  *
23  *    1) Read
24  *    2) Register
25  *    3) Cleanup
26  *
27  *
28  * License:
29  *
30  * This program is free software; you can redistribute it and/or modify
31  * it under the terms of the GNU General Public License version 2 as
32  * published by the Free Software Foundation.
33  *
34  * This program is distributed in the hope that it will be useful,
35  * but WITHOUT ANY WARRANTY; without even the implied warranty of
36  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37  * GNU General Public License for more details.
38  *
39  * You should have received a copy of the GNU General Public License
40  * along with this program; if not, write to the Free Software
41  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
42  *
43  *****************************************************************************/
44 
45 
46 /*********** COMMON HEADER FILES ***********/
47 
48 #include "../include/config.h"
49 #include "../include/common.h"
50 #include "../include/objects.h"
51 #include "../include/locations.h"
52 #include "../include/macros.h"
53 
54 /**** CORE OR CGI SPECIFIC HEADER FILES ****/
55 
56 #ifdef NSCORE
57 #include "../include/nagios.h"
58 #endif
59 
60 #ifdef NSCGI
61 #include "../include/cgiutils.h"
62 #endif
63 
64 /**** DATA INPUT-SPECIFIC HEADER FILES ****/
65 
66 #include "xodtemplate.h"
67 
68 #define XOD_NEW   0 /* not seen */
69 #define XOD_SEEN  1 /* seen, but not yet loopy */
70 #define XOD_LOOPY 2 /* loopy */
71 #define XOD_OK    3 /* not loopy */
72 
73 xodtemplate_timeperiod *xodtemplate_timeperiod_list = NULL;
74 xodtemplate_command *xodtemplate_command_list = NULL;
75 xodtemplate_contactgroup *xodtemplate_contactgroup_list = NULL;
76 xodtemplate_hostgroup *xodtemplate_hostgroup_list = NULL;
77 xodtemplate_servicegroup *xodtemplate_servicegroup_list = NULL;
78 xodtemplate_servicedependency *xodtemplate_servicedependency_list = NULL;
79 xodtemplate_serviceescalation *xodtemplate_serviceescalation_list = NULL;
80 xodtemplate_contact *xodtemplate_contact_list = NULL;
81 xodtemplate_host *xodtemplate_host_list = NULL;
82 xodtemplate_service *xodtemplate_service_list = NULL;
83 xodtemplate_hostdependency *xodtemplate_hostdependency_list = NULL;
84 xodtemplate_hostescalation *xodtemplate_hostescalation_list = NULL;
85 xodtemplate_hostextinfo *xodtemplate_hostextinfo_list = NULL;
86 xodtemplate_serviceextinfo *xodtemplate_serviceextinfo_list = NULL;
87 
88 xodtemplate_timeperiod *xodtemplate_timeperiod_list_tail = NULL;
89 xodtemplate_command *xodtemplate_command_list_tail = NULL;
90 xodtemplate_contactgroup *xodtemplate_contactgroup_list_tail = NULL;
91 xodtemplate_hostgroup *xodtemplate_hostgroup_list_tail = NULL;
92 xodtemplate_servicegroup *xodtemplate_servicegroup_list_tail = NULL;
93 xodtemplate_servicedependency *xodtemplate_servicedependency_list_tail = NULL;
94 xodtemplate_serviceescalation *xodtemplate_serviceescalation_list_tail = NULL;
95 xodtemplate_contact *xodtemplate_contact_list_tail = NULL;
96 xodtemplate_host *xodtemplate_host_list_tail = NULL;
97 xodtemplate_service *xodtemplate_service_list_tail = NULL;
98 xodtemplate_hostdependency *xodtemplate_hostdependency_list_tail = NULL;
99 xodtemplate_hostescalation *xodtemplate_hostescalation_list_tail = NULL;
100 xodtemplate_hostextinfo *xodtemplate_hostextinfo_list_tail = NULL;
101 xodtemplate_serviceextinfo *xodtemplate_serviceextinfo_list_tail = NULL;
102 
103 
104 skiplist *xobject_template_skiplists[NUM_XOBJECT_SKIPLISTS];
105 skiplist *xobject_skiplists[NUM_XOBJECT_SKIPLISTS];
106 
107 
108 void *xodtemplate_current_object = NULL;
109 int xodtemplate_current_object_type = XODTEMPLATE_NONE;
110 
111 int xodtemplate_current_config_file = 0;
112 char **xodtemplate_config_files = NULL;
113 
114 int presorted_objects = FALSE;
115 
116 /* xodtemplate id / object counter */
117 static struct object_count xodcount;
118 
119 /* reusable bitmaps for expanding objects */
120 static bitmap *host_map = NULL, *contact_map = NULL;
121 static bitmap *service_map = NULL, *parent_map = NULL;
122 
123 /* These variables are defined in base/utils.c, but as CGIs do not need these
124    we just fake the values for this file */
125 #ifdef NSCGI
126 #define use_precached_objects TRUE
127 #define use_regexp_matches FALSE
128 #define use_true_regexp_matching FALSE
129 #define test_scheduling FALSE
130 #endif
131 
132 /*
133  * simple inheritance macros. o = object, t = template, v = variable
134  * Note that these can be used for inter-object inheritance as well,
135  * so long as the variable names are identical.
136  */
137 #define xod_inherit(o, t, v) \
138 	do { \
139 		if(o->have_##v == FALSE && t->have_##v == TRUE) { \
140 			o->v = t->v; \
141 			o->have_##v = TRUE; \
142 		} \
143 	} while(0)
144 
145 #define xod_inherit_str_nohave(o, t, v) \
146 	do { \
147 		if(o->v == NULL && t->v != NULL) { \
148 			o->v = (char *)strdup(t->v); \
149 		} \
150 	} while(0)
151 
152 #define xod_inherit_str(o, t, v) \
153 	do { \
154 		if(o->have_##v == FALSE && t->have_##v == TRUE) { \
155 			xod_inherit_str_nohave(o, t, v); \
156 			o->have_##v = TRUE; \
157 		} \
158 	} while(0)
159 
160 
161 
162 /* returns the name of a numbered config file */
xodtemplate_config_file_name(int cfgfile)163 static const char *xodtemplate_config_file_name(int cfgfile) {
164 	if(cfgfile <= xodtemplate_current_config_file)
165 		return xodtemplate_config_files[cfgfile - 1];
166 
167 	return "?";
168 	}
169 
170 
171 
172 /******************************************************************/
173 /************* TOP-LEVEL CONFIG DATA INPUT FUNCTION ***************/
174 /******************************************************************/
175 
176 #ifndef NSCGI
xodtemplate_free_template_skiplists(void)177 static void xodtemplate_free_template_skiplists(void) {
178 	int x = 0;
179 
180 	for(x = 0; x < NUM_XOBJECT_SKIPLISTS; x++) {
181 		skiplist_free(&xobject_template_skiplists[x]);
182 		}
183 	}
184 #endif
185 
186 /* process all config files - both core and CGIs pass in name of main config file */
xodtemplate_read_config_data(const char * main_config_file,int options)187 int xodtemplate_read_config_data(const char *main_config_file, int options) {
188 #ifdef NSCORE
189 	char *cfgfile = NULL;
190 	char *config_base_dir = NULL;
191 	char *input = NULL;
192 	char *var = NULL;
193 	char *val = NULL;
194 	double runtime[11];
195 	mmapfile *thefile = NULL;
196 #endif
197 	struct timeval tv[12];
198 	int result = OK;
199 
200 
201 	if(main_config_file == NULL) {
202 #ifdef NSCORE
203 		printf("Error: No main config file passed to object routines!\n");
204 #endif
205 		return ERROR;
206 		}
207 
208 	timing_point("Reading config data from '%s'\n", main_config_file);
209 
210 	/* initialize variables */
211 	xodtemplate_timeperiod_list = NULL;
212 	xodtemplate_command_list = NULL;
213 	xodtemplate_contactgroup_list = NULL;
214 	xodtemplate_hostgroup_list = NULL;
215 	xodtemplate_servicegroup_list = NULL;
216 	xodtemplate_servicedependency_list = NULL;
217 	xodtemplate_serviceescalation_list = NULL;
218 	xodtemplate_contact_list = NULL;
219 	xodtemplate_host_list = NULL;
220 	xodtemplate_service_list = NULL;
221 	xodtemplate_hostdependency_list = NULL;
222 	xodtemplate_hostescalation_list = NULL;
223 	xodtemplate_hostextinfo_list = NULL;
224 	xodtemplate_serviceextinfo_list = NULL;
225 
226 	/* initialize skiplists */
227 	xodtemplate_init_xobject_skiplists();
228 
229 	xodtemplate_current_object = NULL;
230 	xodtemplate_current_object_type = XODTEMPLATE_NONE;
231 
232 	/* allocate memory for 256 config files (increased dynamically) */
233 	xodtemplate_current_config_file = 0;
234 	xodtemplate_config_files = (char **)malloc(256 * sizeof(char *));
235 	if(xodtemplate_config_files == NULL) {
236 #ifdef NSCORE
237 		printf("Unable to allocate memory!\n");
238 #endif
239 		return ERROR;
240 		}
241 
242 	/* are the objects we're reading already pre-sorted? */
243 	presorted_objects = FALSE;
244 #ifdef NSCORE
245 	presorted_objects = (use_precached_objects == TRUE) ? TRUE : FALSE;
246 #endif
247 
248 #ifdef NSCORE
249 	if(test_scheduling == TRUE)
250 		gettimeofday(&tv[0], NULL);
251 
252 	/* only process the precached object file as long as we're not regenerating it and we're not verifying the config */
253 	if(use_precached_objects == TRUE)
254 		result = xodtemplate_process_config_file(object_precache_file, options);
255 
256 	/* process object config files normally... */
257 	else {
258 		/* determine the directory of the main config file */
259 		if((cfgfile = (char *)strdup(main_config_file)) == NULL) {
260 			my_free(xodtemplate_config_files);
261 			printf("Unable to allocate memory!\n");
262 			return ERROR;
263 			}
264 		config_base_dir = (char *)strdup(dirname(cfgfile));
265 		my_free(cfgfile);
266 
267 		/* open the main config file for reading (we need to find all the config files to read) */
268 		if((thefile = mmap_fopen(main_config_file)) == NULL) {
269 			my_free(config_base_dir);
270 			my_free(xodtemplate_config_files);
271 			printf("Unable to open main config file '%s'\n", main_config_file);
272 			return ERROR;
273 			}
274 
275 		/* daemon reads all config files/dirs specified in the main config file */
276 		/* read in all lines from the main config file */
277 		while(1) {
278 
279 			/* free memory */
280 			my_free(input);
281 
282 			/* get the next line */
283 			if((input = mmap_fgets_multiline(thefile)) == NULL)
284 				break;
285 
286 			/* strip input */
287 			strip(input);
288 
289 			/* skip blank lines and comments */
290 			if(input[0] == '#' || input[0] == ';' || input[0] == '\x0')
291 				continue;
292 
293 			if((var = strtok(input, "=")) == NULL)
294 				continue;
295 
296 			if((val = strtok(NULL, "\n")) == NULL)
297 				continue;
298 
299 			/* process a single config file */
300 			if(!strcmp(var, "xodtemplate_config_file") || !strcmp(var, "cfg_file")) {
301 
302 				if(config_base_dir != NULL && val[0] != '/') {
303 					asprintf(&cfgfile, "%s/%s", config_base_dir, val);
304 					}
305 				else
306 					cfgfile = strdup(val);
307 
308 				/* process the config file... */
309 				result = xodtemplate_process_config_file(cfgfile, options);
310 
311 				my_free(cfgfile);
312 
313 				/* if there was an error processing the config file, break out of loop */
314 				if(result == ERROR)
315 					break;
316 				}
317 
318 			/* process all files in a config directory */
319 			else if(!strcmp(var, "xodtemplate_config_dir") || !strcmp(var, "cfg_dir")) {
320 
321 				if(config_base_dir != NULL && val[0] != '/') {
322 					asprintf(&cfgfile, "%s/%s", config_base_dir, val);
323 					}
324 				else
325 					cfgfile = strdup(val);
326 
327 				/* strip trailing / if necessary */
328 				if(cfgfile != NULL && cfgfile[strlen(cfgfile) - 1] == '/')
329 					cfgfile[strlen(cfgfile) - 1] = '\x0';
330 
331 				/* process the config directory... */
332 				result = xodtemplate_process_config_dir(cfgfile, options);
333 
334 				my_free(cfgfile);
335 
336 				/* if there was an error processing the config file, break out of loop */
337 				if(result == ERROR)
338 					break;
339 				}
340 			}
341 
342 		/* free memory and close the file */
343 		my_free(config_base_dir);
344 		my_free(input);
345 		mmap_fclose(thefile);
346 		}
347 
348 	if(test_scheduling == TRUE)
349 		gettimeofday(&tv[1], NULL);
350 #endif
351 
352 #ifdef NSCGI
353 	/* CGIs process only one file - the cached objects file */
354 	result = xodtemplate_process_config_file(object_cache_file, options);
355 #endif
356 	timing_point("Done parsing config files\n");
357 
358 #ifdef NSCORE
359 
360 	/* only perform intensive operations if we're not using the precached object file */
361 	if(use_precached_objects == FALSE) {
362 
363 		/* resolve objects definitions */
364 		if(result == OK)
365 			result = xodtemplate_resolve_objects();
366 		timing_point("Done resolving objects\n");
367 
368 		/* these are no longer needed */
369 		xodtemplate_free_template_skiplists();
370 
371 		if(test_scheduling == TRUE)
372 			gettimeofday(&tv[2], NULL);
373 
374 		/* cleanup some additive inheritance stuff... */
375 		xodtemplate_clean_additive_strings();
376 		}
377 #endif
378 
379 	/* do the meat and potatoes stuff... */
380 	host_map = bitmap_create(xodcount.hosts);
381 	contact_map = bitmap_create(xodcount.contacts);
382 	if(!host_map || !contact_map) {
383 		logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Failed to create bitmaps for resolving objects\n");
384 		return ERROR;
385 		}
386 
387 	if(result == OK)
388 		result = xodtemplate_recombobulate_contactgroups();
389 	if(test_scheduling == TRUE)
390 		gettimeofday(&tv[3], NULL);
391 	timing_point("Done recombobulating contactgroups\n");
392 
393 	if(result == OK)
394 		result = xodtemplate_recombobulate_hostgroups();
395 	if(test_scheduling == TRUE)
396 		gettimeofday(&tv[4], NULL);
397 	timing_point("Done recombobulating hostgroups\n");
398 
399 #ifndef NSCGI
400 	if(use_precached_objects == FALSE) {
401 		if(result == OK)
402 			result = xodtemplate_duplicate_services();
403 		if(test_scheduling == TRUE)
404 			gettimeofday(&tv[5], NULL);
405 		timing_point("Created %u services (dupes possible)\n", xodcount.services);
406 		}
407 #endif
408 
409 	/* now we have an accurate service count */
410 	service_map = bitmap_create(xodcount.services);
411 	if(!service_map) {
412 		logit(NSLOG_CONFIG_ERROR, TRUE, "Failed to create service map\n");
413 		return ERROR;
414 		}
415 
416 	if(result == OK)
417 		result = xodtemplate_recombobulate_servicegroups();
418 	if(test_scheduling == TRUE)
419 		gettimeofday(&tv[6], NULL);
420 	timing_point("Done recombobulating servicegroups\n");
421 
422 #ifndef NSCGI
423 	if(use_precached_objects == FALSE) {
424 		if(result == OK)
425 			result = xodtemplate_duplicate_objects();
426 		if(test_scheduling == TRUE)
427 			gettimeofday(&tv[7], NULL);
428 
429 		/* NOTE: some missing defaults (notification options, etc.) are also applied here */
430 		if(result == OK)
431 			result = xodtemplate_inherit_object_properties();
432 		timing_point("Done propagating inherited object properties\n");
433 		if(test_scheduling == TRUE)
434 			gettimeofday(&tv[8], NULL);
435 		}
436 #endif
437 
438 	if(test_scheduling == TRUE)
439 		gettimeofday(&tv[9], NULL);
440 
441 
442 	/* register objects */
443 
444 /* Commented out because functions above (xodtemplate_duplicate_objects
445 	in this particular case) return an error without printing any error
446 	messages, so nothing will say what was wrong. */
447 /*	if(result == OK) */
448 		result |= xodtemplate_register_objects();
449 	if(test_scheduling == TRUE)
450 		gettimeofday(&tv[10], NULL);
451 
452 	/* cleanup */
453 	xodtemplate_free_memory();
454 #ifdef NSCORE
455 	if(test_scheduling == TRUE) {
456 		gettimeofday(&tv[11], NULL);
457 
458 		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);
459 		if(use_precached_objects == FALSE) {
460 			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);
461 			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);
462 			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);
463 			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);
464 			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);
465 			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);
466 			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);
467 			runtime[8] = (double)((double)(tv[10].tv_sec - tv[9].tv_sec) + (double)((tv[10].tv_usec - tv[9].tv_usec) / 1000.0) / 1000.0);
468 			}
469 		else {
470 			runtime[1] = 0.0;
471 			runtime[2] = 0.0;
472 			runtime[3] = 0.0;
473 			runtime[4] = 0.0;
474 			runtime[5] = 0.0;
475 			runtime[6] = 0.0;
476 			runtime[7] = 0.0;
477 			runtime[8] = (double)((double)(tv[10].tv_sec - tv[1].tv_sec) + (double)((tv[10].tv_usec - tv[1].tv_usec) / 1000.0) / 1000.0);
478 			}
479 		runtime[9] = (double)((double)(tv[11].tv_sec - tv[10].tv_sec) + (double)((tv[11].tv_usec - tv[10].tv_usec) / 1000.0) / 1000.0);
480 		runtime[10] = (double)((double)(tv[11].tv_sec - tv[0].tv_sec) + (double)((tv[11].tv_usec - tv[0].tv_usec) / 1000.0) / 1000.0);
481 
482 		printf("Timing information on object configuration processing is listed\n");
483 		printf("below.  You can use this information to see if precaching your\n");
484 		printf("object configuration would be useful.\n\n");
485 
486 		printf("Object Config Source: %s\n\n", (use_precached_objects == TRUE) ? "Pre-cached config file" : "Config files (uncached)");
487 
488 		printf("OBJECT CONFIG PROCESSING TIMES      (* = Potential for precache savings with -u option)\n");
489 		printf("----------------------------------\n");
490 		printf("Read:                 %.6lf sec\n", runtime[0]);
491 		printf("Resolve:              %.6lf sec  *\n", runtime[1]);
492 		printf("Recomb Contactgroups: %.6lf sec  *\n", runtime[2]);
493 		printf("Recomb Hostgroups:    %.6lf sec  *\n", runtime[3]);
494 		printf("Dup Services:         %.6lf sec  *\n", runtime[4]);
495 		printf("Recomb Servicegroups: %.6lf sec  *\n", runtime[5]);
496 		printf("Duplicate:            %.6lf sec  *\n", runtime[6]);
497 		printf("Inherit:              %.6lf sec  *\n", runtime[7]);
498 		printf("Register:             %.6lf sec\n", runtime[8]);
499 		printf("Free:                 %.6lf sec\n", runtime[9]);
500 		printf("                      ============\n");
501 		printf("TOTAL:                %.6lf sec  ", runtime[10]);
502 		if(use_precached_objects == FALSE)
503 			printf("* = %.6lf sec (%.2f%%) estimated savings", (runtime[10] - runtime[9] - runtime[8] - runtime[0]) / 4, ((runtime[10] - runtime[9] - runtime[8] - runtime[0]) / runtime[10]) * 25.0);
504 		printf("\n");
505 		printf("\n\n");
506 		}
507 #endif
508 
509 	bitmap_destroy(contact_map);
510 	bitmap_destroy(host_map);
511 	bitmap_destroy(service_map);
512 
513 	return result;
514 	}
515 
516 /* Destructively handles semicolons in the nagios configuration language.
517  * Escaped semicolons "\\;" are turned into semicolons
518  * The first non-escaped semicolon indicates the start of a comment,
519  * and the string is truncated at this point.
520  */
xodtemplate_handle_semicolons(char * input)521 void xodtemplate_handle_semicolons(char* input) {
522 
523 	/* These two integers only come into play if there are escaped semicolons. */
524 	int dest_end = 0; /* The index to input that we need to copy to */
525 	int src_start = 0; /* The index to input that we need to copy from */
526 
527 	register int x = 0;
528 
529 	/* grab data before comment delimiter - faster than a strtok() and strncpy()... */
530 	for(x = 0; input[x] != '\x0'; x++) {
531 		if(input[x] == ';') {
532 			if(x == 0 || input[x - 1] != '\\') {
533 				break;
534 				}
535 
536 			/* We need to escape semicolons */
537 			if (dest_end == 0) {
538 				/* src_start is also uninitialized */
539 				dest_end = x - 1;
540 				src_start = x;
541 				continue;
542 				}
543 
544 			/* dest_end and src_start are initialized - we need to do a copy. */
545 			/* Copy from src_start (usually a semicolon) up to just before the blackslash */
546 			int copy_size = (x - 1) - src_start;
547 			memmove(input + dest_end, input + src_start, copy_size);
548 			dest_end += copy_size;
549 			src_start = x;
550 			}
551 		}
552 
553 	if (dest_end != 0) {
554 		memmove(input + dest_end, input + src_start, x - src_start);
555 		x += dest_end - src_start;
556 		}
557 
558 	input[x] = '\x0';
559 
560 }
561 
562 
563 /* process all files in a specific config directory */
xodtemplate_process_config_dir(char * dirname,int options)564 int xodtemplate_process_config_dir(char *dirname, int options) {
565 	char file[MAX_FILENAME_LENGTH];
566 	DIR *dirp = NULL;
567 	struct dirent *dirfile = NULL;
568 	int result = OK;
569 	register int x = 0;
570 	struct stat stat_buf;
571 
572 #ifdef NSCORE
573 	if(verify_config >= 2)
574 		printf("Processing object config directory '%s'...\n", dirname);
575 #endif
576 
577 	/* open the directory for reading */
578 	dirp = opendir(dirname);
579 	if(dirp == NULL) {
580 		logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not open config directory '%s' for reading.\n", dirname);
581 		return ERROR;
582 		}
583 
584 	/* process all files in the directory... */
585 	while((dirfile = readdir(dirp)) != NULL) {
586 
587 		/* skip hidden files and directories, and current and parent dir */
588 		if(dirfile->d_name[0] == '.')
589 			continue;
590 
591 		/* create /path/to/file */
592 		snprintf(file, sizeof(file), "%s/%s", dirname, dirfile->d_name);
593 		file[sizeof(file) - 1] = '\x0';
594 
595 		/* process this if it's a non-hidden config file... */
596 		if(stat(file, &stat_buf) == -1) {
597 			logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Could not open config directory member '%s' for reading.\n", file);
598 			closedir(dirp);
599 			return ERROR;
600 			}
601 
602 		switch(stat_buf.st_mode & S_IFMT) {
603 
604 			case S_IFREG:
605 				x = strlen(dirfile->d_name);
606 				if(x <= 4 || strcmp(dirfile->d_name + (x - 4), ".cfg"))
607 					break;
608 
609 				/* process the config file */
610 				result = xodtemplate_process_config_file(file, options);
611 
612 				if(result == ERROR) {
613 					closedir(dirp);
614 					return ERROR;
615 					}
616 
617 				break;
618 
619 			case S_IFDIR:
620 				/* recurse into subdirectories... */
621 				result = xodtemplate_process_config_dir(file, options);
622 
623 				if(result == ERROR) {
624 					closedir(dirp);
625 					return ERROR;
626 					}
627 
628 				break;
629 
630 			default:
631 				/* everything else we ignore */
632 				break;
633 			}
634 		}
635 
636 	closedir(dirp);
637 
638 	return result;
639 	}
640 
641 
642 /* process data in a specific config file */
xodtemplate_process_config_file(char * filename,int options)643 int xodtemplate_process_config_file(char *filename, int options) {
644 	mmapfile *thefile = NULL;
645 	char *input = NULL;
646 	register int in_definition = FALSE;
647 	register int current_line = 0;
648 	int result = OK;
649 	register int x = 0;
650 	register int y = 0;
651 	char *ptr = NULL;
652 
653 
654 #ifdef NSCORE
655 	if(verify_config >= 2)
656 		printf("Processing object config file '%s'...\n", filename);
657 #endif
658 
659 	/* save config file name */
660 	xodtemplate_config_files[xodtemplate_current_config_file++] = (char *)strdup(filename);
661 
662 	/* reallocate memory for config files */
663 	if(!(xodtemplate_current_config_file % 256)) {
664 		xodtemplate_config_files = (char **)realloc(xodtemplate_config_files, (xodtemplate_current_config_file + 256) * sizeof(char *));
665 		if(xodtemplate_config_files == NULL)
666 			return ERROR;
667 		}
668 
669 	/* open the config file for reading */
670 	if((thefile = mmap_fopen(filename)) == NULL) {
671 		logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Cannot open config file '%s' for reading: %s\n", filename, strerror(errno));
672 		return ERROR;
673 		}
674 
675 	/* read in all lines from the config file */
676 	while(1) {
677 
678 		/* free memory */
679 		my_free(input);
680 
681 		/* read the next line */
682 		if((input = mmap_fgets_multiline(thefile)) == NULL)
683 			break;
684 
685 		current_line = thefile->current_line;
686 
687 		/* Remove comments and handle escaped semicolons */
688 		xodtemplate_handle_semicolons(input);
689 
690 		/* strip input */
691 		strip(input);
692 
693 		/* skip empty lines */
694 		if(input[0] == '\x0' || input[0] == '#')
695 			continue;
696 
697 		/* this is the start of an object definition */
698 		if(strstr(input, "define") == input) {
699 
700 			/* get the type of object we're defining... */
701 			for(x = 6; input[x] != '\x0'; x++)
702 				if(input[x] != ' ' && input[x] != '\t')
703 					break;
704 			for(y = 0; input[x] != '\x0'; x++) {
705 				if(input[x] == ' ' || input[x] == '\t' ||  input[x] == '{')
706 					break;
707 				else
708 					input[y++] = input[x];
709 				}
710 			input[y] = '\x0';
711 
712 			/* make sure an object type is specified... */
713 			if(input[0] == '\x0') {
714 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: No object type specified in file '%s' on line %d.\n", filename, current_line);
715 				result = ERROR;
716 				break;
717 				}
718 
719 			/* check validity of object type */
720 			if(    strcmp(input, "timeperiod")
721 				&& strcmp(input, "command")
722 				&& strcmp(input, "contact")
723 				&& strcmp(input, "contactgroup")
724 				&& strcmp(input, "host")
725 				&& strcmp(input, "hostgroup")
726 				&& strcmp(input, "servicegroup")
727 				&& strcmp(input, "service")
728 				&& strcmp(input, "servicedependency")
729 				&& strcmp(input, "serviceescalation")
730 				&& strcmp(input, "hostgroupescalation")
731 				&& strcmp(input, "hostdependency")
732 				&& strcmp(input, "hostescalation")) {
733 
734 				if (   strcmp(input, "hostextinfo")
735 				    && strcmp(input, "serviceextinfo")) {
736 
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 				logit(NSLOG_CONFIG_WARNING, TRUE, "WARNING: Extinfo objects are deprecated and will be removed in future versions\n");
743 			}
744 
745 			/* we're already in an object definition... */
746 			if(in_definition == TRUE) {
747 				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);
748 				result = ERROR;
749 				break;
750 				}
751 
752 			/* start a new definition */
753 			if(xodtemplate_begin_object_definition(input, options, xodtemplate_current_config_file, current_line) == ERROR) {
754 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add object definition in file '%s' on line %d.\n", filename, current_line);
755 				result = ERROR;
756 				break;
757 				}
758 
759 			in_definition = TRUE;
760 			}
761 
762 		/* we're currently inside an object definition */
763 		else if(in_definition == TRUE) {
764 
765 			/* this is the close of an object definition */
766 			if(!strcmp(input, "}")) {
767 
768 				in_definition = FALSE;
769 
770 				/* close out current definition */
771 				if(xodtemplate_end_object_definition(options) == ERROR) {
772 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not complete object definition in file '%s' on line %d. Have you named all your objects?\n", filename, current_line);
773 					result = ERROR;
774 					break;
775 					}
776 				}
777 
778 			/* this is a directive inside an object definition */
779 			else {
780 
781 				/* add directive to object definition */
782 				if(xodtemplate_add_object_property(input, options) == ERROR) {
783 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add object property in file '%s' on line %d.\n", filename, current_line);
784 					result = ERROR;
785 					break;
786 					}
787 				}
788 			}
789 
790 		/* include another file */
791 		else if(strstr(input, "include_file=") == input) {
792 
793 			ptr = strtok(input, "=");
794 			ptr = strtok(NULL, "\n");
795 
796 			if(ptr != NULL) {
797 				result = xodtemplate_process_config_file(ptr, options);
798 				if(result == ERROR)
799 					break;
800 				}
801 			}
802 
803 		/* include a directory */
804 		else if(strstr(input, "include_dir") == input) {
805 
806 			ptr = strtok(input, "=");
807 			ptr = strtok(NULL, "\n");
808 
809 			if(ptr != NULL) {
810 				result = xodtemplate_process_config_dir(ptr, options);
811 				if(result == ERROR)
812 					break;
813 				}
814 			}
815 
816 		/* unexpected token or statement */
817 		else {
818 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Unexpected token or statement in file '%s' on line %d.\n", filename, current_line);
819 			result = ERROR;
820 			break;
821 			}
822 		}
823 
824 	/* free memory and close file */
825 	my_free(input);
826 	mmap_fclose(thefile);
827 
828 	/* whoops - EOF while we were in the middle of an object definition... */
829 	if(in_definition == TRUE && result == OK) {
830 		logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Unexpected EOF in file '%s' on line %d - check for a missing closing bracket.\n", filename, current_line);
831 		result = ERROR;
832 		}
833 
834 	return result;
835 	}
836 
837 
838 
839 
840 
841 /******************************************************************/
842 /***************** OBJECT DEFINITION FUNCTIONS ********************/
843 /******************************************************************/
844 
845 /*
846  * all objects start the same way, so we can get rid of quite
847  * a lot of code with this struct-offset-insensitive macro
848  */
849 #define xod_begin_def(type) \
850 	do { \
851 		new_##type = (xodtemplate_##type *)calloc(1, sizeof(*new_##type)); \
852 		if (new_##type == NULL) \
853 			return ERROR; \
854 		new_##type->register_object=TRUE; \
855 		new_##type->_config_file=cfgfile; \
856 		new_##type->_start_line=start_line; \
857 	\
858 		/* precached object files are already sorted, so add to tail */ \
859 		if(presorted_objects==TRUE){ \
860 			\
861 			if(xodtemplate_##type##_list==NULL){ \
862 				xodtemplate_##type##_list=new_##type; \
863 				xodtemplate_##type##_list_tail=xodtemplate_##type##_list; \
864 			} else { \
865 				xodtemplate_##type##_list_tail->next=new_##type; \
866 				xodtemplate_##type##_list_tail=new_##type; \
867 			} \
868 	\
869 			/* update current object pointer */ \
870 			xodtemplate_current_object=xodtemplate_##type##_list_tail; \
871 		} else { \
872 			/* add new object to head of list in memory */ \
873 			new_##type->next=xodtemplate_##type##_list; \
874 			xodtemplate_##type##_list=new_##type; \
875 	\
876 			/* update current object pointer */ \
877 			xodtemplate_current_object=xodtemplate_##type##_list; \
878 		} \
879 	} while (0)
880 
881 /* starts a new object definition */
xodtemplate_begin_object_definition(char * input,int options,int cfgfile,int start_line)882 int xodtemplate_begin_object_definition(char *input, int options, int cfgfile, int start_line) {
883 	int result = OK;
884 	xodtemplate_timeperiod *new_timeperiod = NULL;
885 	xodtemplate_command *new_command = NULL;
886 	xodtemplate_contactgroup *new_contactgroup = NULL;
887 	xodtemplate_hostgroup *new_hostgroup = NULL;
888 	xodtemplate_servicegroup *new_servicegroup = NULL;
889 	xodtemplate_servicedependency *new_servicedependency = NULL;
890 	xodtemplate_serviceescalation *new_serviceescalation = NULL;
891 	xodtemplate_contact *new_contact = NULL;
892 	xodtemplate_host *new_host = NULL;
893 	xodtemplate_service *new_service = NULL;
894 	xodtemplate_hostdependency *new_hostdependency = NULL;
895 	xodtemplate_hostescalation *new_hostescalation = NULL;
896 	xodtemplate_hostextinfo *new_hostextinfo = NULL;
897 	xodtemplate_serviceextinfo *new_serviceextinfo = NULL;
898 
899 	if(!strcmp(input, "service"))
900 		xodtemplate_current_object_type = XODTEMPLATE_SERVICE;
901 	else if(!strcmp(input, "host"))
902 		xodtemplate_current_object_type = XODTEMPLATE_HOST;
903 	else if(!strcmp(input, "command"))
904 		xodtemplate_current_object_type = XODTEMPLATE_COMMAND;
905 	else if(!strcmp(input, "contact"))
906 		xodtemplate_current_object_type = XODTEMPLATE_CONTACT;
907 	else if(!strcmp(input, "contactgroup"))
908 		xodtemplate_current_object_type = XODTEMPLATE_CONTACTGROUP;
909 	else if(!strcmp(input, "hostgroup"))
910 		xodtemplate_current_object_type = XODTEMPLATE_HOSTGROUP;
911 	else if(!strcmp(input, "servicegroup"))
912 		xodtemplate_current_object_type = XODTEMPLATE_SERVICEGROUP;
913 	else if(!strcmp(input, "timeperiod"))
914 		xodtemplate_current_object_type = XODTEMPLATE_TIMEPERIOD;
915 	else if(!strcmp(input, "servicedependency"))
916 		xodtemplate_current_object_type = XODTEMPLATE_SERVICEDEPENDENCY;
917 	else if(!strcmp(input, "serviceescalation"))
918 		xodtemplate_current_object_type = XODTEMPLATE_SERVICEESCALATION;
919 	else if(!strcmp(input, "hostdependency"))
920 		xodtemplate_current_object_type = XODTEMPLATE_HOSTDEPENDENCY;
921 	else if(!strcmp(input, "hostescalation"))
922 		xodtemplate_current_object_type = XODTEMPLATE_HOSTESCALATION;
923 	else if(!strcmp(input, "hostextinfo"))
924 		xodtemplate_current_object_type = XODTEMPLATE_HOSTEXTINFO;
925 	else if(!strcmp(input, "serviceextinfo"))
926 		xodtemplate_current_object_type = XODTEMPLATE_SERVICEEXTINFO;
927 	else
928 		return ERROR;
929 
930 
931 	/* check to see if we should process this type of object */
932 	switch(xodtemplate_current_object_type) {
933 		case XODTEMPLATE_TIMEPERIOD:
934 			if(!(options & READ_TIMEPERIODS))
935 				return OK;
936 			break;
937 		case XODTEMPLATE_COMMAND:
938 			if(!(options & READ_COMMANDS))
939 				return OK;
940 			break;
941 		case XODTEMPLATE_CONTACT:
942 			if(!(options & READ_CONTACTS))
943 				return OK;
944 			break;
945 		case XODTEMPLATE_CONTACTGROUP:
946 			if(!(options & READ_CONTACTGROUPS))
947 				return OK;
948 			break;
949 		case XODTEMPLATE_HOST:
950 			if(!(options & READ_HOSTS))
951 				return OK;
952 			break;
953 		case XODTEMPLATE_HOSTGROUP:
954 			if(!(options & READ_HOSTGROUPS))
955 				return OK;
956 			break;
957 		case XODTEMPLATE_SERVICEGROUP:
958 			if(!(options & READ_SERVICEGROUPS))
959 				return OK;
960 			break;
961 		case XODTEMPLATE_SERVICE:
962 			if(!(options & READ_SERVICES))
963 				return OK;
964 			break;
965 		case XODTEMPLATE_SERVICEDEPENDENCY:
966 			if(!(options & READ_SERVICEDEPENDENCIES))
967 				return OK;
968 			break;
969 		case XODTEMPLATE_SERVICEESCALATION:
970 			if(!(options & READ_SERVICEESCALATIONS))
971 				return OK;
972 			break;
973 		case XODTEMPLATE_HOSTDEPENDENCY:
974 			if(!(options & READ_HOSTDEPENDENCIES))
975 				return OK;
976 			break;
977 		case XODTEMPLATE_HOSTESCALATION:
978 			if(!(options & READ_HOSTESCALATIONS))
979 				return OK;
980 			break;
981 		case XODTEMPLATE_HOSTEXTINFO:
982 			if(!(options & READ_HOSTEXTINFO))
983 				return OK;
984 			break;
985 		case XODTEMPLATE_SERVICEEXTINFO:
986 			if(!(options & READ_SERVICEEXTINFO))
987 				return OK;
988 			break;
989 		default:
990 			return ERROR;
991 			break;
992 		}
993 
994 
995 
996 	/* add a new (blank) object */
997 	switch(xodtemplate_current_object_type) {
998 
999 		case XODTEMPLATE_TIMEPERIOD:
1000 			xod_begin_def(timeperiod);
1001 			break;
1002 
1003 		case XODTEMPLATE_COMMAND:
1004 			xod_begin_def(command);
1005 			break;
1006 
1007 		case XODTEMPLATE_CONTACTGROUP:
1008 			xod_begin_def(contactgroup);
1009 			break;
1010 
1011 		case XODTEMPLATE_HOSTGROUP:
1012 			xod_begin_def(hostgroup);
1013 			break;
1014 
1015 		case XODTEMPLATE_SERVICEGROUP:
1016 			xod_begin_def(servicegroup);
1017 			break;
1018 
1019 		case XODTEMPLATE_SERVICEDEPENDENCY:
1020 			xod_begin_def(servicedependency);
1021 			break;
1022 
1023 		case XODTEMPLATE_SERVICEESCALATION:
1024 			xod_begin_def(serviceescalation);
1025 			new_serviceescalation->first_notification = -2;
1026 			new_serviceescalation->last_notification = -2;
1027 			break;
1028 
1029 		case XODTEMPLATE_CONTACT:
1030 			xod_begin_def(contact);
1031 
1032 			new_contact->minimum_value = 0;
1033 			new_contact->host_notifications_enabled = TRUE;
1034 			new_contact->service_notifications_enabled = TRUE;
1035 			new_contact->can_submit_commands = TRUE;
1036 			new_contact->retain_status_information = TRUE;
1037 			new_contact->retain_nonstatus_information = TRUE;
1038 			break;
1039 
1040 		case XODTEMPLATE_HOST:
1041 			xod_begin_def(host);
1042 
1043 			new_host->hourly_value = 0;
1044 			new_host->check_interval = 5.0;
1045 			new_host->retry_interval = 1.0;
1046 			new_host->active_checks_enabled = TRUE;
1047 			new_host->passive_checks_enabled = TRUE;
1048 			new_host->obsess = TRUE;
1049 			new_host->max_check_attempts = -2;
1050 			new_host->event_handler_enabled = TRUE;
1051 			new_host->flap_detection_enabled = TRUE;
1052 			new_host->flap_detection_options = OPT_ALL;
1053 			new_host->notifications_enabled = TRUE;
1054 			new_host->notification_interval = 30.0;
1055 			new_host->process_perf_data = TRUE;
1056 			new_host->x_2d = -1;
1057 			new_host->y_2d = -1;
1058 			new_host->retain_status_information = TRUE;
1059 			new_host->retain_nonstatus_information = TRUE;
1060 			break;
1061 
1062 		case XODTEMPLATE_SERVICE:
1063 			xod_begin_def(service);
1064 
1065 			new_service->hourly_value = 0;
1066 			new_service->initial_state = STATE_OK;
1067 			new_service->max_check_attempts = -2;
1068 			new_service->check_interval = 5.0;
1069 			new_service->retry_interval = 1.0;
1070 			new_service->active_checks_enabled = TRUE;
1071 			new_service->passive_checks_enabled = TRUE;
1072 			new_service->parallelize_check = TRUE;
1073 			new_service->obsess = TRUE;
1074 			new_service->event_handler_enabled = TRUE;
1075 			new_service->flap_detection_enabled = TRUE;
1076 			new_service->flap_detection_options = OPT_ALL;
1077 			new_service->notifications_enabled = TRUE;
1078 			new_service->notification_interval = 30.0;
1079 			new_service->process_perf_data = 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 */
1084 			new_service->is_from_hostgroup = 0;
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 
xodtemplate_type_name(unsigned int id)1117 static const char *xodtemplate_type_name(unsigned int id) {
1118 	static const char *otype_name[] = {
1119 		"NONE", "timeperiod", "command", "contact", "contactgroup",
1120 		"host", "hostgroup", "service", "servicedependency",
1121 		"serviceescalation", "hostescalation", "hostdependency",
1122 		"hostextinfo", "serviceextinfo", "servicegroup"
1123 	};
1124 	if (id > ARRAY_SIZE(otype_name))
1125 		return otype_name[0];
1126 	return otype_name[id];
1127 
1128 	}
1129 
xodtemplate_obsoleted(const char * var,int start_line)1130 static void xodtemplate_obsoleted(const char *var, int start_line) {
1131 	logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: %s is obsoleted and no longer has any effect in %s type objects (config file '%s', starting at line %d)\n",
1132 		 var, xodtemplate_type_name(xodtemplate_current_object_type),
1133 		 xodtemplate_config_file_name(xodtemplate_current_config_file), start_line);
1134 	}
1135 
1136 /* adds a property to an object definition */
xodtemplate_add_object_property(char * input,int options)1137 int xodtemplate_add_object_property(char *input, int options) {
1138 	int result = OK;
1139 	char *variable = NULL;
1140 	char *value = NULL;
1141 	char *temp_ptr = NULL;
1142 	char *customvarname = NULL;
1143 	char *customvarvalue = NULL;
1144 	xodtemplate_timeperiod *temp_timeperiod = NULL;
1145 	xodtemplate_command *temp_command = NULL;
1146 	xodtemplate_contactgroup *temp_contactgroup = NULL;
1147 	xodtemplate_hostgroup *temp_hostgroup = NULL;
1148 	xodtemplate_servicegroup *temp_servicegroup = NULL;
1149 	xodtemplate_servicedependency *temp_servicedependency = NULL;
1150 	xodtemplate_serviceescalation *temp_serviceescalation = NULL;
1151 	xodtemplate_contact *temp_contact = NULL;
1152 	xodtemplate_host *temp_host = NULL;
1153 	xodtemplate_service *temp_service = NULL;
1154 	xodtemplate_hostdependency *temp_hostdependency = NULL;
1155 	xodtemplate_hostescalation *temp_hostescalation = NULL;
1156 	xodtemplate_hostextinfo *temp_hostextinfo = NULL;
1157 	xodtemplate_serviceextinfo *temp_serviceextinfo = NULL;
1158 	int x, lth, force_skiplists = FALSE;
1159 
1160 
1161 	/* should some object definitions be added to skiplists immediately? */
1162 #ifdef NSCORE
1163 	if(use_precached_objects == TRUE)
1164 		force_skiplists = TRUE;
1165 #else
1166 	force_skiplists = TRUE;
1167 #endif
1168 
1169 	/* check to see if we should process this type of object */
1170 	switch(xodtemplate_current_object_type) {
1171 		case XODTEMPLATE_TIMEPERIOD:
1172 			if(!(options & READ_TIMEPERIODS))
1173 				return OK;
1174 			break;
1175 		case XODTEMPLATE_COMMAND:
1176 			if(!(options & READ_COMMANDS))
1177 				return OK;
1178 			break;
1179 		case XODTEMPLATE_CONTACT:
1180 			if(!(options & READ_CONTACTS))
1181 				return OK;
1182 			break;
1183 		case XODTEMPLATE_CONTACTGROUP:
1184 			if(!(options & READ_CONTACTGROUPS))
1185 				return OK;
1186 			break;
1187 		case XODTEMPLATE_HOST:
1188 			if(!(options & READ_HOSTS))
1189 				return OK;
1190 			break;
1191 		case XODTEMPLATE_HOSTGROUP:
1192 			if(!(options & READ_HOSTGROUPS))
1193 				return OK;
1194 			break;
1195 		case XODTEMPLATE_SERVICEGROUP:
1196 			if(!(options & READ_SERVICEGROUPS))
1197 				return OK;
1198 			break;
1199 		case XODTEMPLATE_SERVICE:
1200 			if(!(options & READ_SERVICES))
1201 				return OK;
1202 			break;
1203 		case XODTEMPLATE_SERVICEDEPENDENCY:
1204 			if(!(options & READ_SERVICEDEPENDENCIES))
1205 				return OK;
1206 			break;
1207 		case XODTEMPLATE_SERVICEESCALATION:
1208 			if(!(options & READ_SERVICEESCALATIONS))
1209 				return OK;
1210 			break;
1211 		case XODTEMPLATE_HOSTDEPENDENCY:
1212 			if(!(options & READ_HOSTDEPENDENCIES))
1213 				return OK;
1214 			break;
1215 		case XODTEMPLATE_HOSTESCALATION:
1216 			if(!(options & READ_HOSTESCALATIONS))
1217 				return OK;
1218 			break;
1219 		case XODTEMPLATE_HOSTEXTINFO:
1220 			if(!(options & READ_HOSTEXTINFO))
1221 				return OK;
1222 			break;
1223 		case XODTEMPLATE_SERVICEEXTINFO:
1224 			if(!(options & READ_SERVICEEXTINFO))
1225 				return OK;
1226 			break;
1227 		default:
1228 			return ERROR;
1229 			break;
1230 		}
1231 
1232 	/* get variable name */
1233 	variable = input;
1234 	lth = strlen(variable);
1235 	/* trim at first whitespace occurrence */
1236 	for(x = 0; variable[x] != '\x0'; x++) {
1237 		if(variable[x] == ' ' || variable[x] == '\t') {
1238 			variable[x] = 0;
1239 			break;
1240 			}
1241 		}
1242 
1243 	/* get variable value */
1244 	if (x == lth)
1245 		value = "";
1246 	else
1247 		value = input + x + 1;
1248 	while (*value == ' ' || *value == '\t')
1249 		value++;
1250 	/* now strip trailing spaces */
1251 	strip(value);
1252 
1253 	switch(xodtemplate_current_object_type) {
1254 
1255 		case XODTEMPLATE_TIMEPERIOD:
1256 
1257 			temp_timeperiod = (xodtemplate_timeperiod *)xodtemplate_current_object;
1258 
1259 			if(!strcmp(variable, "use")) {
1260 				if((temp_timeperiod->template = (char *)strdup(value)) == NULL)
1261 					result = ERROR;
1262 				}
1263 			else if(!strcmp(variable, "name")) {
1264 
1265 				if((temp_timeperiod->name = (char *)strdup(value)) == NULL)
1266 					result = ERROR;
1267 
1268 				if(result == OK) {
1269 					/* add timeperiod to template skiplist for fast searches */
1270 					result = skiplist_insert(xobject_template_skiplists[TIMEPERIOD_SKIPLIST], (void *)temp_timeperiod);
1271 					switch(result) {
1272 						case SKIPLIST_ERROR_DUPLICATE:
1273 							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);
1274 							result = ERROR;
1275 							break;
1276 						case SKIPLIST_OK:
1277 							result = OK;
1278 							break;
1279 						default:
1280 							result = ERROR;
1281 							break;
1282 						}
1283 					}
1284 				}
1285 			else if(!strcmp(variable, "timeperiod_name")) {
1286 				if((temp_timeperiod->timeperiod_name = (char *)strdup(value)) == NULL)
1287 					result = ERROR;
1288 
1289 				if(result == OK) {
1290 					/* add timeperiod to template skiplist for fast searches */
1291 					result = skiplist_insert(xobject_skiplists[TIMEPERIOD_SKIPLIST], (void *)temp_timeperiod);
1292 					switch(result) {
1293 						case SKIPLIST_ERROR_DUPLICATE:
1294 							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);
1295 							result = ERROR;
1296 							break;
1297 						case SKIPLIST_OK:
1298 							result = OK;
1299 							break;
1300 						default:
1301 							result = ERROR;
1302 							break;
1303 						}
1304 					}
1305 				}
1306 			else if(!strcmp(variable, "alias")) {
1307 				if((temp_timeperiod->alias = (char *)strdup(value)) == NULL)
1308 					result = ERROR;
1309 				}
1310 			else if(!strcmp(variable, "exclude")) {
1311 				if((temp_timeperiod->exclusions = (char *)strdup(value)) == NULL)
1312 					result = ERROR;
1313 				}
1314 			else if(!strcmp(variable, "register"))
1315 				temp_timeperiod->register_object = (atoi(value) > 0) ? TRUE : FALSE;
1316 			else if(xodtemplate_parse_timeperiod_directive(temp_timeperiod, variable, value) == OK)
1317 				result = OK;
1318 			else {
1319 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid timeperiod object directive '%s'.\n", variable);
1320 				return ERROR;
1321 				}
1322 			break;
1323 
1324 
1325 
1326 		case XODTEMPLATE_COMMAND:
1327 
1328 			temp_command = (xodtemplate_command *)xodtemplate_current_object;
1329 
1330 			if(!strcmp(variable, "use")) {
1331 				if((temp_command->template = (char *)strdup(value)) == NULL)
1332 					result = ERROR;
1333 				}
1334 			else if(!strcmp(variable, "name")) {
1335 				if((temp_command->name = (char *)strdup(value)) == NULL)
1336 					result = ERROR;
1337 
1338 				if(result == OK) {
1339 					/* add command to template skiplist for fast searches */
1340 					result = skiplist_insert(xobject_template_skiplists[COMMAND_SKIPLIST], (void *)temp_command);
1341 					switch(result) {
1342 						case SKIPLIST_ERROR_DUPLICATE:
1343 							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);
1344 							result = ERROR;
1345 							break;
1346 						case SKIPLIST_OK:
1347 							result = OK;
1348 							break;
1349 						default:
1350 							result = ERROR;
1351 							break;
1352 						}
1353 					}
1354 				}
1355 			else if(!strcmp(variable, "command_name")) {
1356 				if((temp_command->command_name = (char *)strdup(value)) == NULL)
1357 					result = ERROR;
1358 
1359 				if(result == OK) {
1360 					/* add command to template skiplist for fast searches */
1361 					result = skiplist_insert(xobject_skiplists[COMMAND_SKIPLIST], (void *)temp_command);
1362 					switch(result) {
1363 						case SKIPLIST_ERROR_DUPLICATE:
1364 							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);
1365 							result = ERROR;
1366 							break;
1367 						case SKIPLIST_OK:
1368 							result = OK;
1369 							break;
1370 						default:
1371 							result = ERROR;
1372 							break;
1373 						}
1374 					}
1375 				}
1376 			else if(!strcmp(variable, "command_line")) {
1377 				if((temp_command->command_line = (char *)strdup(value)) == NULL)
1378 					result = ERROR;
1379 				}
1380 			else if(!strcmp(variable, "register"))
1381 				temp_command->register_object = (atoi(value) > 0) ? TRUE : FALSE;
1382 			else {
1383 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid command object directive '%s'.\n", variable);
1384 				return ERROR;
1385 				}
1386 
1387 			break;
1388 
1389 		case XODTEMPLATE_CONTACTGROUP:
1390 
1391 			temp_contactgroup = (xodtemplate_contactgroup *)xodtemplate_current_object;
1392 
1393 			if(!strcmp(variable, "use")) {
1394 				if((temp_contactgroup->template = (char *)strdup(value)) == NULL)
1395 					result = ERROR;
1396 				}
1397 			else if(!strcmp(variable, "name")) {
1398 
1399 				if((temp_contactgroup->name = (char *)strdup(value)) == NULL)
1400 					result = ERROR;
1401 
1402 				if(result == OK) {
1403 					/* add contactgroup to template skiplist for fast searches */
1404 					result = skiplist_insert(xobject_template_skiplists[CONTACTGROUP_SKIPLIST], (void *)temp_contactgroup);
1405 					switch(result) {
1406 						case SKIPLIST_ERROR_DUPLICATE:
1407 							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);
1408 							result = ERROR;
1409 							break;
1410 						case SKIPLIST_OK:
1411 							result = OK;
1412 							break;
1413 						default:
1414 							result = ERROR;
1415 							break;
1416 						}
1417 					}
1418 				}
1419 			else if(!strcmp(variable, "contactgroup_name")) {
1420 				if((temp_contactgroup->contactgroup_name = (char *)strdup(value)) == NULL)
1421 					result = ERROR;
1422 
1423 				if(result == OK) {
1424 					/* add contactgroup to template skiplist for fast searches */
1425 					result = skiplist_insert(xobject_skiplists[CONTACTGROUP_SKIPLIST], (void *)temp_contactgroup);
1426 					switch(result) {
1427 						case SKIPLIST_ERROR_DUPLICATE:
1428 							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);
1429 							result = ERROR;
1430 							break;
1431 						case SKIPLIST_OK:
1432 							result = OK;
1433 							break;
1434 						default:
1435 							result = ERROR;
1436 							break;
1437 						}
1438 					}
1439 				}
1440 			else if(!strcmp(variable, "alias")) {
1441 				if((temp_contactgroup->alias = (char *)strdup(value)) == NULL)
1442 					result = ERROR;
1443 				}
1444 			else if(!strcmp(variable, "members")) {
1445 				if(strcmp(value, XODTEMPLATE_NULL)) {
1446 					if(temp_contactgroup->members == NULL)
1447 						temp_contactgroup->members = (char *)strdup(value);
1448 					else {
1449 						temp_contactgroup->members = (char *)realloc(temp_contactgroup->members, strlen(temp_contactgroup->members) + strlen(value) + 2);
1450 						if(temp_contactgroup->members != NULL) {
1451 							strcat(temp_contactgroup->members, ",");
1452 							strcat(temp_contactgroup->members, value);
1453 							}
1454 						}
1455 					if(temp_contactgroup->members == NULL)
1456 						result = ERROR;
1457 					}
1458 				temp_contactgroup->have_members = TRUE;
1459 				}
1460 			else if(!strcmp(variable, "contactgroup_members")) {
1461 				if(strcmp(value, XODTEMPLATE_NULL)) {
1462 					if(temp_contactgroup->contactgroup_members == NULL)
1463 						temp_contactgroup->contactgroup_members = (char *)strdup(value);
1464 					else {
1465 						temp_contactgroup->contactgroup_members = (char *)realloc(temp_contactgroup->contactgroup_members, strlen(temp_contactgroup->contactgroup_members) + strlen(value) + 2);
1466 						if(temp_contactgroup->contactgroup_members != NULL) {
1467 							strcat(temp_contactgroup->contactgroup_members, ",");
1468 							strcat(temp_contactgroup->contactgroup_members, value);
1469 							}
1470 						}
1471 					if(temp_contactgroup->contactgroup_members == NULL)
1472 						result = ERROR;
1473 					}
1474 				temp_contactgroup->have_contactgroup_members = TRUE;
1475 				}
1476 			else if(!strcmp(variable, "register"))
1477 				temp_contactgroup->register_object = (atoi(value) > 0) ? TRUE : FALSE;
1478 			else {
1479 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid contactgroup object directive '%s'.\n", variable);
1480 				return ERROR;
1481 				}
1482 
1483 			break;
1484 
1485 		case XODTEMPLATE_HOSTGROUP:
1486 
1487 			temp_hostgroup = (xodtemplate_hostgroup *)xodtemplate_current_object;
1488 
1489 			if(!strcmp(variable, "use")) {
1490 				if((temp_hostgroup->template = (char *)strdup(value)) == NULL)
1491 					result = ERROR;
1492 				}
1493 			else if(!strcmp(variable, "name")) {
1494 
1495 				if((temp_hostgroup->name = (char *)strdup(value)) == NULL)
1496 					result = ERROR;
1497 
1498 				if(result == OK) {
1499 					/* add hostgroup to template skiplist for fast searches */
1500 					result = skiplist_insert(xobject_template_skiplists[HOSTGROUP_SKIPLIST], (void *)temp_hostgroup);
1501 					switch(result) {
1502 						case SKIPLIST_ERROR_DUPLICATE:
1503 							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);
1504 							result = ERROR;
1505 							break;
1506 						case SKIPLIST_OK:
1507 							result = OK;
1508 							break;
1509 						default:
1510 							result = ERROR;
1511 							break;
1512 						}
1513 					}
1514 				}
1515 			else if(!strcmp(variable, "hostgroup_name")) {
1516 				if((temp_hostgroup->hostgroup_name = (char *)strdup(value)) == NULL)
1517 					result = ERROR;
1518 
1519 				if(result == OK) {
1520 					/* add hostgroup to template skiplist for fast searches */
1521 					result = skiplist_insert(xobject_skiplists[HOSTGROUP_SKIPLIST], (void *)temp_hostgroup);
1522 					switch(result) {
1523 						case SKIPLIST_ERROR_DUPLICATE:
1524 							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);
1525 							result = ERROR;
1526 							break;
1527 						case SKIPLIST_OK:
1528 							result = OK;
1529 							break;
1530 						default:
1531 							result = ERROR;
1532 							break;
1533 						}
1534 					}
1535 				}
1536 			else if(!strcmp(variable, "alias")) {
1537 				if((temp_hostgroup->alias = (char *)strdup(value)) == NULL)
1538 					result = ERROR;
1539 				}
1540 			else if(!strcmp(variable, "members")) {
1541 				if(strcmp(value, XODTEMPLATE_NULL)) {
1542 					if(temp_hostgroup->members == NULL)
1543 						temp_hostgroup->members = (char *)strdup(value);
1544 					else {
1545 						temp_hostgroup->members = (char *)realloc(temp_hostgroup->members, strlen(temp_hostgroup->members) + strlen(value) + 2);
1546 						if(temp_hostgroup->members != NULL) {
1547 							strcat(temp_hostgroup->members, ",");
1548 							strcat(temp_hostgroup->members, value);
1549 							}
1550 						}
1551 					if(temp_hostgroup->members == NULL)
1552 						result = ERROR;
1553 					}
1554 				temp_hostgroup->have_members = TRUE;
1555 				}
1556 			else if(!strcmp(variable, "hostgroup_members")) {
1557 				if(strcmp(value, XODTEMPLATE_NULL)) {
1558 					if(temp_hostgroup->hostgroup_members == NULL)
1559 						temp_hostgroup->hostgroup_members = (char *)strdup(value);
1560 					else {
1561 						temp_hostgroup->hostgroup_members = (char *)realloc(temp_hostgroup->hostgroup_members, strlen(temp_hostgroup->hostgroup_members) + strlen(value) + 2);
1562 						if(temp_hostgroup->hostgroup_members != NULL) {
1563 							strcat(temp_hostgroup->hostgroup_members, ",");
1564 							strcat(temp_hostgroup->hostgroup_members, value);
1565 							}
1566 						}
1567 					if(temp_hostgroup->hostgroup_members == NULL)
1568 						result = ERROR;
1569 					}
1570 				temp_hostgroup->have_hostgroup_members = TRUE;
1571 				}
1572 			else if(!strcmp(variable, "notes")) {
1573 				if(strcmp(value, XODTEMPLATE_NULL)) {
1574 					if((temp_hostgroup->notes = (char *)strdup(value)) == NULL)
1575 						result = ERROR;
1576 					}
1577 				temp_hostgroup->have_notes = TRUE;
1578 				}
1579 			else if(!strcmp(variable, "notes_url")) {
1580 				if(strcmp(value, XODTEMPLATE_NULL)) {
1581 					if((temp_hostgroup->notes_url = (char *)strdup(value)) == NULL)
1582 						result = ERROR;
1583 					}
1584 				temp_hostgroup->have_notes_url = TRUE;
1585 				}
1586 			else if(!strcmp(variable, "action_url")) {
1587 				if(strcmp(value, XODTEMPLATE_NULL)) {
1588 					if((temp_hostgroup->action_url = (char *)strdup(value)) == NULL)
1589 						result = ERROR;
1590 					}
1591 				temp_hostgroup->have_action_url = TRUE;
1592 				}
1593 			else if(!strcmp(variable, "register"))
1594 				temp_hostgroup->register_object = (atoi(value) > 0) ? TRUE : FALSE;
1595 			else {
1596 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid hostgroup object directive '%s'.\n", variable);
1597 				return ERROR;
1598 				}
1599 
1600 			break;
1601 
1602 
1603 		case XODTEMPLATE_SERVICEGROUP:
1604 
1605 			temp_servicegroup = (xodtemplate_servicegroup *)xodtemplate_current_object;
1606 
1607 			if(!strcmp(variable, "use")) {
1608 				if((temp_servicegroup->template = (char *)strdup(value)) == NULL)
1609 					result = ERROR;
1610 				}
1611 			else if(!strcmp(variable, "name")) {
1612 
1613 				if((temp_servicegroup->name = (char *)strdup(value)) == NULL)
1614 					result = ERROR;
1615 
1616 				if(result == OK) {
1617 					/* add servicegroup to template skiplist for fast searches */
1618 					result = skiplist_insert(xobject_template_skiplists[SERVICEGROUP_SKIPLIST], (void *)temp_servicegroup);
1619 					switch(result) {
1620 						case SKIPLIST_ERROR_DUPLICATE:
1621 							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);
1622 							result = ERROR;
1623 							break;
1624 						case SKIPLIST_OK:
1625 							result = OK;
1626 							break;
1627 						default:
1628 							result = ERROR;
1629 							break;
1630 						}
1631 					}
1632 				}
1633 			else if(!strcmp(variable, "servicegroup_name")) {
1634 				if((temp_servicegroup->servicegroup_name = (char *)strdup(value)) == NULL)
1635 					result = ERROR;
1636 
1637 				if(result == OK) {
1638 					/* add servicegroup to template skiplist for fast searches */
1639 					result = skiplist_insert(xobject_skiplists[SERVICEGROUP_SKIPLIST], (void *)temp_servicegroup);
1640 					switch(result) {
1641 						case SKIPLIST_ERROR_DUPLICATE:
1642 							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);
1643 							result = ERROR;
1644 							break;
1645 						case SKIPLIST_OK:
1646 							result = OK;
1647 							break;
1648 						default:
1649 							result = ERROR;
1650 							break;
1651 						}
1652 					}
1653 				}
1654 			else if(!strcmp(variable, "alias")) {
1655 				if((temp_servicegroup->alias = (char *)strdup(value)) == NULL)
1656 					result = ERROR;
1657 				}
1658 			else if(!strcmp(variable, "members")) {
1659 				if(strcmp(value, XODTEMPLATE_NULL)) {
1660 					if(temp_servicegroup->members == NULL)
1661 						temp_servicegroup->members = (char *)strdup(value);
1662 					else {
1663 						temp_servicegroup->members = (char *)realloc(temp_servicegroup->members, strlen(temp_servicegroup->members) + strlen(value) + 2);
1664 						if(temp_servicegroup->members != NULL) {
1665 							strcat(temp_servicegroup->members, ",");
1666 							strcat(temp_servicegroup->members, value);
1667 							}
1668 						}
1669 					if(temp_servicegroup->members == NULL)
1670 						result = ERROR;
1671 					}
1672 				temp_servicegroup->have_members = TRUE;
1673 				}
1674 			else if(!strcmp(variable, "servicegroup_members")) {
1675 				if(strcmp(value, XODTEMPLATE_NULL)) {
1676 					if(temp_servicegroup->servicegroup_members == NULL)
1677 						temp_servicegroup->servicegroup_members = (char *)strdup(value);
1678 					else {
1679 						temp_servicegroup->servicegroup_members = (char *)realloc(temp_servicegroup->servicegroup_members, strlen(temp_servicegroup->servicegroup_members) + strlen(value) + 2);
1680 						if(temp_servicegroup->servicegroup_members != NULL) {
1681 							strcat(temp_servicegroup->servicegroup_members, ",");
1682 							strcat(temp_servicegroup->servicegroup_members, value);
1683 							}
1684 						}
1685 					if(temp_servicegroup->servicegroup_members == NULL)
1686 						result = ERROR;
1687 					}
1688 				temp_servicegroup->have_servicegroup_members = TRUE;
1689 				}
1690 			else if(!strcmp(variable, "notes")) {
1691 				if(strcmp(value, XODTEMPLATE_NULL)) {
1692 					if((temp_servicegroup->notes = (char *)strdup(value)) == NULL)
1693 						result = ERROR;
1694 					}
1695 				temp_servicegroup->have_notes = TRUE;
1696 				}
1697 			else if(!strcmp(variable, "notes_url")) {
1698 				if(strcmp(value, XODTEMPLATE_NULL)) {
1699 					if((temp_servicegroup->notes_url = (char *)strdup(value)) == NULL)
1700 						result = ERROR;
1701 					}
1702 				temp_servicegroup->have_notes_url = TRUE;
1703 				}
1704 			else if(!strcmp(variable, "action_url")) {
1705 				if(strcmp(value, XODTEMPLATE_NULL)) {
1706 					if((temp_servicegroup->action_url = (char *)strdup(value)) == NULL)
1707 						result = ERROR;
1708 					}
1709 				temp_servicegroup->have_action_url = TRUE;
1710 				}
1711 			else if(!strcmp(variable, "register"))
1712 				temp_servicegroup->register_object = (atoi(value) > 0) ? TRUE : FALSE;
1713 			else {
1714 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid servicegroup object directive '%s'.\n", variable);
1715 				return ERROR;
1716 				}
1717 
1718 			break;
1719 
1720 
1721 		case XODTEMPLATE_SERVICEDEPENDENCY:
1722 
1723 			temp_servicedependency = (xodtemplate_servicedependency *)xodtemplate_current_object;
1724 
1725 			if(!strcmp(variable, "use")) {
1726 				if((temp_servicedependency->template = (char *)strdup(value)) == NULL)
1727 					result = ERROR;
1728 				}
1729 			else if(!strcmp(variable, "name")) {
1730 
1731 				if((temp_servicedependency->name = (char *)strdup(value)) == NULL)
1732 					result = ERROR;
1733 
1734 				if(result == OK) {
1735 					/* add dependency to template skiplist for fast searches */
1736 					result = skiplist_insert(xobject_template_skiplists[SERVICEDEPENDENCY_SKIPLIST], (void *)temp_servicedependency);
1737 					switch(result) {
1738 						case SKIPLIST_ERROR_DUPLICATE:
1739 							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);
1740 							result = ERROR;
1741 							break;
1742 						case SKIPLIST_OK:
1743 							result = OK;
1744 							break;
1745 						default:
1746 							result = ERROR;
1747 							break;
1748 						}
1749 					}
1750 				}
1751 			else if(!strcmp(variable, "servicegroup") || !strcmp(variable, "servicegroups") || !strcmp(variable, "servicegroup_name")) {
1752 				if(strcmp(value, XODTEMPLATE_NULL)) {
1753 					if((temp_servicedependency->servicegroup_name = (char *)strdup(value)) == NULL)
1754 						result = ERROR;
1755 					}
1756 				temp_servicedependency->have_servicegroup_name = TRUE;
1757 				}
1758 			else if(!strcmp(variable, "hostgroup") || !strcmp(variable, "hostgroups") || !strcmp(variable, "hostgroup_name")) {
1759 				if(strcmp(value, XODTEMPLATE_NULL)) {
1760 					if((temp_servicedependency->hostgroup_name = (char *)strdup(value)) == NULL)
1761 						result = ERROR;
1762 					}
1763 				temp_servicedependency->have_hostgroup_name = TRUE;
1764 				}
1765 			else if(!strcmp(variable, "host") || !strcmp(variable, "host_name") || !strcmp(variable, "master_host") || !strcmp(variable, "master_host_name")) {
1766 				if(strcmp(value, XODTEMPLATE_NULL)) {
1767 					if((temp_servicedependency->host_name = (char *)strdup(value)) == NULL)
1768 						result = ERROR;
1769 					}
1770 				temp_servicedependency->have_host_name = TRUE;
1771 				}
1772 			else if(!strcmp(variable, "description") || !strcmp(variable, "service_description") || !strcmp(variable, "master_description") || !strcmp(variable, "master_service_description")) {
1773 				if(strcmp(value, XODTEMPLATE_NULL)) {
1774 					if((temp_servicedependency->service_description = (char *)strdup(value)) == NULL)
1775 						result = ERROR;
1776 					}
1777 				temp_servicedependency->have_service_description = TRUE;
1778 				}
1779 			else if(!strcmp(variable, "dependent_servicegroup") || !strcmp(variable, "dependent_servicegroups") || !strcmp(variable, "dependent_servicegroup_name")) {
1780 				if(strcmp(value, XODTEMPLATE_NULL)) {
1781 					if((temp_servicedependency->dependent_servicegroup_name = (char *)strdup(value)) == NULL)
1782 						result = ERROR;
1783 					}
1784 				temp_servicedependency->have_dependent_servicegroup_name = TRUE;
1785 				}
1786 			else if(!strcmp(variable, "dependent_hostgroup") || !strcmp(variable, "dependent_hostgroups") || !strcmp(variable, "dependent_hostgroup_name")) {
1787 				if(strcmp(value, XODTEMPLATE_NULL)) {
1788 					if((temp_servicedependency->dependent_hostgroup_name = (char *)strdup(value)) == NULL)
1789 						result = ERROR;
1790 					}
1791 				temp_servicedependency->have_dependent_hostgroup_name = TRUE;
1792 				}
1793 			else if(!strcmp(variable, "dependent_host") || !strcmp(variable, "dependent_host_name")) {
1794 				if(strcmp(value, XODTEMPLATE_NULL)) {
1795 					if((temp_servicedependency->dependent_host_name = (char *)strdup(value)) == NULL)
1796 						result = ERROR;
1797 					}
1798 				temp_servicedependency->have_dependent_host_name = TRUE;
1799 				}
1800 			else if(!strcmp(variable, "dependent_description") || !strcmp(variable, "dependent_service_description")) {
1801 				if(strcmp(value, XODTEMPLATE_NULL)) {
1802 					if((temp_servicedependency->dependent_service_description = (char *)strdup(value)) == NULL)
1803 						result = ERROR;
1804 					}
1805 				temp_servicedependency->have_dependent_service_description = TRUE;
1806 				}
1807 			else if(!strcmp(variable, "dependency_period")) {
1808 				if(strcmp(value, XODTEMPLATE_NULL)) {
1809 					if((temp_servicedependency->dependency_period = (char *)strdup(value)) == NULL)
1810 						result = ERROR;
1811 					}
1812 				temp_servicedependency->have_dependency_period = TRUE;
1813 				}
1814 			else if(!strcmp(variable, "inherits_parent")) {
1815 				temp_servicedependency->inherits_parent = (atoi(value) > 0) ? TRUE : FALSE;
1816 				temp_servicedependency->have_inherits_parent = TRUE;
1817 				}
1818 			else if(!strcmp(variable, "execution_failure_options") || !strcmp(variable, "execution_failure_criteria")) {
1819 				temp_servicedependency->have_execution_failure_options = TRUE;
1820 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
1821 					if(!strcmp(temp_ptr, "o") || !strcmp(temp_ptr, "ok"))
1822 						flag_set(temp_servicedependency->execution_failure_options, OPT_OK);
1823 					else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unknown"))
1824 						flag_set(temp_servicedependency->execution_failure_options, OPT_UNKNOWN);
1825 					else if(!strcmp(temp_ptr, "w") || !strcmp(temp_ptr, "warning"))
1826 						flag_set(temp_servicedependency->execution_failure_options, OPT_WARNING);
1827 					else if(!strcmp(temp_ptr, "c") || !strcmp(temp_ptr, "critical"))
1828 						flag_set(temp_servicedependency->execution_failure_options, OPT_CRITICAL);
1829 					else if(!strcmp(temp_ptr, "p") || !strcmp(temp_ptr, "pending"))
1830 						flag_set(temp_servicedependency->execution_failure_options, OPT_PENDING);
1831 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
1832 						temp_servicedependency->execution_failure_options = OPT_NOTHING;
1833 						temp_servicedependency->have_execution_failure_options = FALSE;
1834 						}
1835 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
1836 						temp_servicedependency->execution_failure_options = OPT_ALL;
1837 						}
1838 					else {
1839 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid execution dependency option '%s' in servicedependency definition.\n", temp_ptr);
1840 						return ERROR;
1841 						}
1842 					}
1843 				}
1844 			else if(!strcmp(variable, "notification_failure_options") || !strcmp(variable, "notification_failure_criteria")) {
1845 				temp_servicedependency->have_notification_failure_options = TRUE;
1846 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
1847 					if(!strcmp(temp_ptr, "o") || !strcmp(temp_ptr, "ok"))
1848 						flag_set(temp_servicedependency->notification_failure_options, OPT_OK);
1849 					else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unknown"))
1850 						flag_set(temp_servicedependency->notification_failure_options, OPT_UNKNOWN);
1851 					else if(!strcmp(temp_ptr, "w") || !strcmp(temp_ptr, "warning"))
1852 						flag_set(temp_servicedependency->notification_failure_options, OPT_WARNING);
1853 					else if(!strcmp(temp_ptr, "c") || !strcmp(temp_ptr, "critical"))
1854 						flag_set(temp_servicedependency->notification_failure_options, OPT_CRITICAL);
1855 					else if(!strcmp(temp_ptr, "p") || !strcmp(temp_ptr, "pending"))
1856 						flag_set(temp_servicedependency->notification_failure_options, OPT_PENDING);
1857 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
1858 						temp_servicedependency->notification_failure_options = OPT_NOTHING;
1859 						temp_servicedependency->have_notification_failure_options = FALSE;
1860 						}
1861 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
1862 						temp_servicedependency->notification_failure_options = OPT_ALL;
1863 						}
1864 					else {
1865 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid notification dependency option '%s' in servicedependency definition.\n", temp_ptr);
1866 						return ERROR;
1867 						}
1868 					}
1869 				}
1870 			else if(!strcmp(variable, "register"))
1871 				temp_servicedependency->register_object = (atoi(value) > 0) ? TRUE : FALSE;
1872 			else {
1873 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid servicedependency object directive '%s'.\n", variable);
1874 				return ERROR;
1875 				}
1876 
1877 			break;
1878 
1879 
1880 		case XODTEMPLATE_SERVICEESCALATION:
1881 
1882 			temp_serviceescalation = (xodtemplate_serviceescalation *)xodtemplate_current_object;
1883 
1884 			if(!strcmp(variable, "use")) {
1885 				if((temp_serviceescalation->template = (char *)strdup(value)) == NULL)
1886 					result = ERROR;
1887 				}
1888 			else if(!strcmp(variable, "name")) {
1889 
1890 				if((temp_serviceescalation->name = (char *)strdup(value)) == NULL)
1891 					result = ERROR;
1892 
1893 				if(result == OK) {
1894 					/* add escalation to template skiplist for fast searches */
1895 					result = skiplist_insert(xobject_template_skiplists[SERVICEESCALATION_SKIPLIST], (void *)temp_serviceescalation);
1896 					switch(result) {
1897 						case SKIPLIST_ERROR_DUPLICATE:
1898 							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);
1899 							result = ERROR;
1900 							break;
1901 						case SKIPLIST_OK:
1902 							result = OK;
1903 							break;
1904 						default:
1905 							result = ERROR;
1906 							break;
1907 						}
1908 					}
1909 				}
1910 			else if(!strcmp(variable, "host") || !strcmp(variable, "host_name")) {
1911 
1912 				if(strcmp(value, XODTEMPLATE_NULL)) {
1913 					if((temp_serviceescalation->host_name = (char *)strdup(value)) == NULL)
1914 						result = ERROR;
1915 					}
1916 				temp_serviceescalation->have_host_name = TRUE;
1917 				}
1918 			else if(!strcmp(variable, "description") || !strcmp(variable, "service_description")) {
1919 				if(strcmp(value, XODTEMPLATE_NULL)) {
1920 					if((temp_serviceescalation->service_description = (char *)strdup(value)) == NULL)
1921 						result = ERROR;
1922 					}
1923 				temp_serviceescalation->have_service_description = TRUE;
1924 				}
1925 			else if(!strcmp(variable, "servicegroup") || !strcmp(variable, "servicegroups") || !strcmp(variable, "servicegroup_name")) {
1926 				if(strcmp(value, XODTEMPLATE_NULL)) {
1927 					if((temp_serviceescalation->servicegroup_name = (char *)strdup(value)) == NULL)
1928 						result = ERROR;
1929 					}
1930 				temp_serviceescalation->have_servicegroup_name = TRUE;
1931 				}
1932 			else if(!strcmp(variable, "hostgroup") || !strcmp(variable, "hostgroups") || !strcmp(variable, "hostgroup_name")) {
1933 				if(strcmp(value, XODTEMPLATE_NULL)) {
1934 					if((temp_serviceescalation->hostgroup_name = (char *)strdup(value)) == NULL)
1935 						result = ERROR;
1936 					}
1937 				temp_serviceescalation->have_hostgroup_name = TRUE;
1938 				}
1939 			else if(!strcmp(variable, "contact_groups")) {
1940 				if (*value == '\0') {
1941 					logit(NSLOG_CONFIG_WARNING, TRUE, "Error: Empty value for contact_groups (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_serviceescalation->_config_file), temp_serviceescalation->_start_line);
1942 					result = ERROR;
1943 					break;
1944 				}
1945 				if(strcmp(value, XODTEMPLATE_NULL)) {
1946 					if((temp_serviceescalation->contact_groups = (char *)strdup(value)) == NULL)
1947 						result = ERROR;
1948 					}
1949 				temp_serviceescalation->have_contact_groups = TRUE;
1950 				}
1951 			else if(!strcmp(variable, "contacts")) {
1952 				if (*value == '\0') {
1953 					logit(NSLOG_CONFIG_WARNING, TRUE, "Error: Empty value for contacts (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_serviceescalation->_config_file), temp_serviceescalation->_start_line);
1954 					result = ERROR;
1955 					break;
1956 				}
1957 				if(strcmp(value, XODTEMPLATE_NULL)) {
1958 					if((temp_serviceescalation->contacts = (char *)strdup(value)) == NULL)
1959 						result = ERROR;
1960 					}
1961 				temp_serviceescalation->have_contacts = TRUE;
1962 				}
1963 			else if(!strcmp(variable, "escalation_period")) {
1964 				if(strcmp(value, XODTEMPLATE_NULL)) {
1965 					if((temp_serviceescalation->escalation_period = (char *)strdup(value)) == NULL)
1966 						result = ERROR;
1967 					}
1968 				temp_serviceescalation->have_escalation_period = TRUE;
1969 				}
1970 			else if(!strcmp(variable, "first_notification")) {
1971 				temp_serviceescalation->first_notification = atoi(value);
1972 				temp_serviceescalation->have_first_notification = TRUE;
1973 				}
1974 			else if(!strcmp(variable, "last_notification")) {
1975 				temp_serviceescalation->last_notification = atoi(value);
1976 				temp_serviceescalation->have_last_notification = TRUE;
1977 				}
1978 			else if(!strcmp(variable, "notification_interval")) {
1979 				temp_serviceescalation->notification_interval = strtod(value, NULL);
1980 				temp_serviceescalation->have_notification_interval = TRUE;
1981 				}
1982 			else if(!strcmp(variable, "escalation_options")) {
1983 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
1984 					if(!strcmp(temp_ptr, "w") || !strcmp(temp_ptr, "warning"))
1985 						flag_set(temp_serviceescalation->escalation_options, OPT_WARNING);
1986 					else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unknown"))
1987 						flag_set(temp_serviceescalation->escalation_options, OPT_UNKNOWN);
1988 					else if(!strcmp(temp_ptr, "c") || !strcmp(temp_ptr, "critical"))
1989 						flag_set(temp_serviceescalation->escalation_options, OPT_CRITICAL);
1990 					else if(!strcmp(temp_ptr, "r") || !strcmp(temp_ptr, "recovery"))
1991 						flag_set(temp_serviceescalation->escalation_options, OPT_RECOVERY);
1992 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
1993 						temp_serviceescalation->escalation_options = OPT_NOTHING;
1994 						}
1995 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
1996 						temp_serviceescalation->escalation_options = OPT_ALL;
1997 						}
1998 					else {
1999 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid escalation option '%s' in serviceescalation definition.\n", temp_ptr);
2000 						return ERROR;
2001 						}
2002 					}
2003 				temp_serviceescalation->have_escalation_options = TRUE;
2004 				}
2005 			else if(!strcmp(variable, "register"))
2006 				temp_serviceescalation->register_object = (atoi(value) > 0) ? TRUE : FALSE;
2007 			else {
2008 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid serviceescalation object directive '%s'.\n", variable);
2009 				return ERROR;
2010 				}
2011 
2012 			break;
2013 
2014 
2015 		case XODTEMPLATE_CONTACT:
2016 
2017 			temp_contact = (xodtemplate_contact *)xodtemplate_current_object;
2018 
2019 			if(!strcmp(variable, "use")) {
2020 				if((temp_contact->template = (char *)strdup(value)) == NULL)
2021 					result = ERROR;
2022 				}
2023 			else if(!strcmp(variable, "name")) {
2024 
2025 				if((temp_contact->name = (char *)strdup(value)) == NULL)
2026 					result = ERROR;
2027 
2028 				if(result == OK) {
2029 					/* add contact to template skiplist for fast searches */
2030 					result = skiplist_insert(xobject_template_skiplists[CONTACT_SKIPLIST], (void *)temp_contact);
2031 					switch(result) {
2032 						case SKIPLIST_ERROR_DUPLICATE:
2033 							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);
2034 							result = ERROR;
2035 							break;
2036 						case SKIPLIST_OK:
2037 							result = OK;
2038 							break;
2039 						default:
2040 							result = ERROR;
2041 							break;
2042 						}
2043 					}
2044 				}
2045 			else if(!strcmp(variable, "contact_name")) {
2046 				if((temp_contact->contact_name = (char *)strdup(value)) == NULL)
2047 					result = ERROR;
2048 
2049 				if(result == OK) {
2050 					/* add contact to template skiplist for fast searches */
2051 					result = skiplist_insert(xobject_skiplists[CONTACT_SKIPLIST], (void *)temp_contact);
2052 					switch(result) {
2053 						case SKIPLIST_ERROR_DUPLICATE:
2054 							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);
2055 							result = ERROR;
2056 							break;
2057 						case SKIPLIST_OK:
2058 							result = OK;
2059 							break;
2060 						default:
2061 							result = ERROR;
2062 							break;
2063 						}
2064 					}
2065 				temp_contact->id = xodcount.contacts++;
2066 				}
2067 			else if(!strcmp(variable, "alias")) {
2068 				if((temp_contact->alias = (char *)strdup(value)) == NULL)
2069 					result = ERROR;
2070 				}
2071 			else if(!strcmp(variable, "contact_groups") || !strcmp(variable, "contactgroups")) {
2072 				if(strcmp(value, XODTEMPLATE_NULL)) {
2073 					if((temp_contact->contact_groups = (char *)strdup(value)) == NULL)
2074 						result = ERROR;
2075 					}
2076 				temp_contact->have_contact_groups = TRUE;
2077 				}
2078 			else if(!strcmp(variable, "email")) {
2079 				if(strcmp(value, XODTEMPLATE_NULL)) {
2080 					if((temp_contact->email = (char *)strdup(value)) == NULL)
2081 						result = ERROR;
2082 					}
2083 				temp_contact->have_email = TRUE;
2084 				}
2085 			else if(!strcmp(variable, "pager")) {
2086 				if(strcmp(value, XODTEMPLATE_NULL)) {
2087 					if((temp_contact->pager = (char *)strdup(value)) == NULL)
2088 						result = ERROR;
2089 					}
2090 				temp_contact->have_pager = TRUE;
2091 				}
2092 			else if(strstr(variable, "address") == variable) {
2093 				x = atoi(variable + 7);
2094 				if(x < 1 || x > MAX_XODTEMPLATE_CONTACT_ADDRESSES)
2095 					result = ERROR;
2096 				else if(strcmp(value, XODTEMPLATE_NULL)) {
2097 					if((temp_contact->address[x - 1] = (char *)strdup(value)) == NULL)
2098 						result = ERROR;
2099 					}
2100 				if(result == OK)
2101 					temp_contact->have_address[x - 1] = TRUE;
2102 				}
2103 			else if(!strcmp(variable, "host_notification_period")) {
2104 				if(strcmp(value, XODTEMPLATE_NULL)) {
2105 					if((temp_contact->host_notification_period = (char *)strdup(value)) == NULL)
2106 						result = ERROR;
2107 					}
2108 				temp_contact->have_host_notification_period = TRUE;
2109 				}
2110 			else if(!strcmp(variable, "host_notification_commands")) {
2111 				if(strcmp(value, XODTEMPLATE_NULL)) {
2112 					if((temp_contact->host_notification_commands = (char *)strdup(value)) == NULL)
2113 						result = ERROR;
2114 					}
2115 				temp_contact->have_host_notification_commands = TRUE;
2116 				}
2117 			else if(!strcmp(variable, "service_notification_period")) {
2118 				if(strcmp(value, XODTEMPLATE_NULL)) {
2119 					if((temp_contact->service_notification_period = (char *)strdup(value)) == NULL)
2120 						result = ERROR;
2121 					}
2122 				temp_contact->have_service_notification_period = TRUE;
2123 				}
2124 			else if(!strcmp(variable, "service_notification_commands")) {
2125 				if(strcmp(value, XODTEMPLATE_NULL)) {
2126 					if((temp_contact->service_notification_commands = (char *)strdup(value)) == NULL)
2127 						result = ERROR;
2128 					}
2129 				temp_contact->have_service_notification_commands = TRUE;
2130 				}
2131 			else if(!strcmp(variable, "host_notification_options")) {
2132 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
2133 					if(!strcmp(temp_ptr, "d") || !strcmp(temp_ptr, "down"))
2134 						flag_set(temp_contact->host_notification_options, OPT_DOWN);
2135 					else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unreachable"))
2136 						flag_set(temp_contact->host_notification_options, OPT_UNREACHABLE);
2137 					else if(!strcmp(temp_ptr, "r") || !strcmp(temp_ptr, "recovery"))
2138 						flag_set(temp_contact->host_notification_options, OPT_RECOVERY);
2139 					else if(!strcmp(temp_ptr, "f") || !strcmp(temp_ptr, "flapping"))
2140 						flag_set(temp_contact->host_notification_options, OPT_FLAPPING);
2141 					else if(!strcmp(temp_ptr, "s") || !strcmp(temp_ptr, "downtime"))
2142 						flag_set(temp_contact->host_notification_options, OPT_DOWNTIME);
2143 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
2144 						temp_contact->host_notification_options = OPT_NOTHING;
2145 						}
2146 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
2147 						temp_contact->host_notification_options = OPT_ALL;
2148 						}
2149 					else {
2150 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid host notification option '%s' in contact definition.\n", temp_ptr);
2151 						return ERROR;
2152 						}
2153 					}
2154 				temp_contact->have_host_notification_options = TRUE;
2155 				}
2156 			else if(!strcmp(variable, "service_notification_options")) {
2157 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
2158 					if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unknown"))
2159 						flag_set(temp_contact->service_notification_options, OPT_UNKNOWN);
2160 					else if(!strcmp(temp_ptr, "w") || !strcmp(temp_ptr, "warning"))
2161 						flag_set(temp_contact->service_notification_options, OPT_WARNING);
2162 					else if(!strcmp(temp_ptr, "c") || !strcmp(temp_ptr, "critical"))
2163 						flag_set(temp_contact->service_notification_options, OPT_CRITICAL);
2164 					else if(!strcmp(temp_ptr, "r") || !strcmp(temp_ptr, "recovery"))
2165 						flag_set(temp_contact->service_notification_options, OPT_RECOVERY);
2166 					else if(!strcmp(temp_ptr, "f") || !strcmp(temp_ptr, "flapping"))
2167 						flag_set(temp_contact->service_notification_options, OPT_FLAPPING);
2168 					else if(!strcmp(temp_ptr, "s") || !strcmp(temp_ptr, "downtime"))
2169 						flag_set(temp_contact->service_notification_options, OPT_DOWNTIME);
2170 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
2171 						temp_contact->service_notification_options = OPT_NOTHING;
2172 						}
2173 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
2174 						temp_contact->service_notification_options = OPT_ALL;
2175 						}
2176 					else {
2177 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid service notification option '%s' in contact definition.\n", temp_ptr);
2178 						return ERROR;
2179 						}
2180 					}
2181 				temp_contact->have_service_notification_options = TRUE;
2182 				}
2183 			else if(!strcmp(variable, "host_notifications_enabled")) {
2184 				temp_contact->host_notifications_enabled = (atoi(value) > 0) ? TRUE : FALSE;
2185 				temp_contact->have_host_notifications_enabled = TRUE;
2186 				}
2187 			else if(!strcmp(variable, "service_notifications_enabled")) {
2188 				temp_contact->service_notifications_enabled = (atoi(value) > 0) ? TRUE : FALSE;
2189 				temp_contact->have_service_notifications_enabled = TRUE;
2190 				}
2191 			else if(!strcmp(variable, "can_submit_commands")) {
2192 				temp_contact->can_submit_commands = (atoi(value) > 0) ? TRUE : FALSE;
2193 				temp_contact->have_can_submit_commands = TRUE;
2194 				}
2195 			else if(!strcmp(variable, "retain_status_information")) {
2196 				temp_contact->retain_status_information = (atoi(value) > 0) ? TRUE : FALSE;
2197 				temp_contact->have_retain_status_information = TRUE;
2198 				}
2199 			else if(!strcmp(variable, "retain_nonstatus_information")) {
2200 				temp_contact->retain_nonstatus_information = (atoi(value) > 0) ? TRUE : FALSE;
2201 				temp_contact->have_retain_nonstatus_information = TRUE;
2202 				}
2203 			else if(!strcmp(variable, "minimum_importance") ||
2204 					!strcmp(variable, "minimum_value")) {
2205 				if(!strcmp(variable, "minimum_value")) {
2206 					logit(NSLOG_CONFIG_WARNING, TRUE, "WARNING: The minimum_value attribute is deprecated and will be removed in future versions. Please use minimum_importance instead.\n");
2207 					}
2208 				temp_contact->minimum_value = strtoul(value, NULL, 10);
2209 				temp_contact->have_minimum_value = TRUE;
2210 				}
2211 			else if(!strcmp(variable, "register"))
2212 				temp_contact->register_object = (atoi(value) > 0) ? TRUE : FALSE;
2213 			else if(variable[0] == '_') {
2214 
2215 				/* get the variable name */
2216 				customvarname = (char *)strdup(variable + 1);
2217 
2218 				/* make sure we have a variable name */
2219 				if(customvarname == NULL || !strcmp(customvarname, "")) {
2220 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Null custom variable name.\n");
2221 					my_free(customvarname);
2222 					return ERROR;
2223 					}
2224 
2225 				/* get the variable value */
2226 				if(*value && strcmp(value, XODTEMPLATE_NULL))
2227 					customvarvalue = (char *)strdup(value);
2228 				else
2229 					customvarvalue = NULL;
2230 
2231 				/* add the custom variable */
2232 				if(xodtemplate_add_custom_variable_to_contact(temp_contact, customvarname, customvarvalue) == NULL) {
2233 					my_free(customvarname);
2234 					my_free(customvarvalue);
2235 					return ERROR;
2236 					}
2237 
2238 				/* free memory */
2239 				my_free(customvarname);
2240 				my_free(customvarvalue);
2241 				}
2242 			else {
2243 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid contact object directive '%s'.\n", variable);
2244 				return ERROR;
2245 				}
2246 
2247 			break;
2248 
2249 
2250 		case XODTEMPLATE_HOST:
2251 
2252 			temp_host = (xodtemplate_host *)xodtemplate_current_object;
2253 
2254 			if(!strcmp(variable, "use")) {
2255 				if((temp_host->template = (char *)strdup(value)) == NULL)
2256 					result = ERROR;
2257 				}
2258 			else if(!strcmp(variable, "name")) {
2259 
2260 				if((temp_host->name = (char *)strdup(value)) == NULL)
2261 					result = ERROR;
2262 
2263 				if(result == OK) {
2264 					/* add host to template skiplist for fast searches */
2265 					result = skiplist_insert(xobject_template_skiplists[HOST_SKIPLIST], (void *)temp_host);
2266 					switch(result) {
2267 						case SKIPLIST_ERROR_DUPLICATE:
2268 							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);
2269 							result = ERROR;
2270 							break;
2271 						case SKIPLIST_OK:
2272 							result = OK;
2273 							break;
2274 						default:
2275 							result = ERROR;
2276 							break;
2277 						}
2278 					}
2279 				}
2280 			else if(!strcmp(variable, "host_name")) {
2281 				if((temp_host->host_name = (char *)strdup(value)) == NULL)
2282 					result = ERROR;
2283 
2284 				if(result == OK) {
2285 					/* add host to template skiplist for fast searches */
2286 					result = skiplist_insert(xobject_skiplists[HOST_SKIPLIST], (void *)temp_host);
2287 					switch(result) {
2288 						case SKIPLIST_ERROR_DUPLICATE:
2289 							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);
2290 							result = ERROR;
2291 							break;
2292 						case SKIPLIST_OK:
2293 							result = OK;
2294 							break;
2295 						default:
2296 							result = ERROR;
2297 							break;
2298 						}
2299 					}
2300 				temp_host->id = xodcount.hosts++;
2301 				}
2302 			else if(!strcmp(variable, "display_name")) {
2303 				if(strcmp(value, XODTEMPLATE_NULL)) {
2304 					if((temp_host->display_name = (char *)strdup(value)) == NULL)
2305 						result = ERROR;
2306 					}
2307 				temp_host->have_display_name = TRUE;
2308 				}
2309 			else if(!strcmp(variable, "alias")) {
2310 				if((temp_host->alias = (char *)strdup(value)) == NULL)
2311 					result = ERROR;
2312 				}
2313 			else if(!strcmp(variable, "address")) {
2314 				if((temp_host->address = (char *)strdup(value)) == NULL)
2315 					result = ERROR;
2316 				}
2317 			else if(!strcmp(variable, "parents")) {
2318 				if(strcmp(value, XODTEMPLATE_NULL)) {
2319 					if((temp_host->parents = (char *)strdup(value)) == NULL)
2320 						result = ERROR;
2321 					}
2322 				temp_host->have_parents = TRUE;
2323 				}
2324 			else if(!strcmp(variable, "host_groups") || !strcmp(variable, "hostgroups")) {
2325 				if(strcmp(value, XODTEMPLATE_NULL)) {
2326 					if((temp_host->host_groups = (char *)strdup(value)) == NULL)
2327 						result = ERROR;
2328 					}
2329 				temp_host->have_host_groups = TRUE;
2330 				}
2331 			else if(!strcmp(variable, "contact_groups")) {
2332 				if (*value == '\0') {
2333 					logit(NSLOG_CONFIG_WARNING, TRUE, "Error: Empty value for contact_groups (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_host->_config_file), temp_host->_start_line);
2334 					result = ERROR;
2335 					break;
2336 				}
2337 				if(strcmp(value, XODTEMPLATE_NULL)) {
2338 					if((temp_host->contact_groups = (char *)strdup(value)) == NULL)
2339 						result = ERROR;
2340 					}
2341 				temp_host->have_contact_groups = TRUE;
2342 				}
2343 			else if(!strcmp(variable, "contacts")) {
2344 				if (*value == '\0') {
2345 					logit(NSLOG_CONFIG_WARNING, TRUE, "Error: Empty value for contacts (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_host->_config_file), temp_host->_start_line);
2346 					result = ERROR;
2347 					break;
2348 				}
2349 				if(strcmp(value, XODTEMPLATE_NULL)) {
2350 					if((temp_host->contacts = (char *)strdup(value)) == NULL)
2351 						result = ERROR;
2352 					}
2353 				temp_host->have_contacts = TRUE;
2354 				}
2355 			else if(!strcmp(variable, "notification_period")) {
2356 				if(strcmp(value, XODTEMPLATE_NULL)) {
2357 					if((temp_host->notification_period = (char *)strdup(value)) == NULL)
2358 						result = ERROR;
2359 					}
2360 				temp_host->have_notification_period = TRUE;
2361 				}
2362 			else if(!strcmp(variable, "check_command")) {
2363 				if(strcmp(value, XODTEMPLATE_NULL)) {
2364 					if((temp_host->check_command = (char *)strdup(value)) == NULL)
2365 						result = ERROR;
2366 					}
2367 				temp_host->have_check_command = TRUE;
2368 				}
2369 			else if(!strcmp(variable, "check_period")) {
2370 				if(strcmp(value, XODTEMPLATE_NULL)) {
2371 					if((temp_host->check_period = (char *)strdup(value)) == NULL)
2372 						result = ERROR;
2373 					}
2374 				temp_host->have_check_period = TRUE;
2375 				}
2376 			else if(!strcmp(variable, "event_handler")) {
2377 				if(strcmp(value, XODTEMPLATE_NULL)) {
2378 					if((temp_host->event_handler = (char *)strdup(value)) == NULL)
2379 						result = ERROR;
2380 					}
2381 				temp_host->have_event_handler = TRUE;
2382 				}
2383 			else if(!strcmp(variable, "failure_prediction_options")) {
2384 				xodtemplate_obsoleted(variable, temp_host->_start_line);
2385 				}
2386 			else if(!strcmp(variable, "notes")) {
2387 				if(strcmp(value, XODTEMPLATE_NULL)) {
2388 					if((temp_host->notes = (char *)strdup(value)) == NULL)
2389 						result = ERROR;
2390 					}
2391 				temp_host->have_notes = TRUE;
2392 				}
2393 			else if(!strcmp(variable, "notes_url")) {
2394 				if(strcmp(value, XODTEMPLATE_NULL)) {
2395 					if((temp_host->notes_url = (char *)strdup(value)) == NULL)
2396 						result = ERROR;
2397 					}
2398 				temp_host->have_notes_url = TRUE;
2399 				}
2400 			else if(!strcmp(variable, "action_url")) {
2401 				if(strcmp(value, XODTEMPLATE_NULL)) {
2402 					if((temp_host->action_url = (char *)strdup(value)) == NULL)
2403 						result = ERROR;
2404 					}
2405 				temp_host->have_action_url = TRUE;
2406 				}
2407 			else if(!strcmp(variable, "icon_image")) {
2408 				if(strcmp(value, XODTEMPLATE_NULL)) {
2409 					if((temp_host->icon_image = (char *)strdup(value)) == NULL)
2410 						result = ERROR;
2411 					}
2412 				temp_host->have_icon_image = TRUE;
2413 				}
2414 			else if(!strcmp(variable, "icon_image_alt")) {
2415 				if(strcmp(value, XODTEMPLATE_NULL)) {
2416 					if((temp_host->icon_image_alt = (char *)strdup(value)) == NULL)
2417 						result = ERROR;
2418 					}
2419 				temp_host->have_icon_image_alt = TRUE;
2420 				}
2421 			else if(!strcmp(variable, "vrml_image")) {
2422 				if(strcmp(value, XODTEMPLATE_NULL)) {
2423 					if((temp_host->vrml_image = (char *)strdup(value)) == NULL)
2424 						result = ERROR;
2425 					}
2426 				temp_host->have_vrml_image = TRUE;
2427 				}
2428 			else if(!strcmp(variable, "gd2_image") || !strcmp(variable, "statusmap_image")) {
2429 				if(strcmp(value, XODTEMPLATE_NULL)) {
2430 					if((temp_host->statusmap_image = (char *)strdup(value)) == NULL)
2431 						result = ERROR;
2432 					}
2433 				temp_host->have_statusmap_image = TRUE;
2434 				}
2435 			else if(!strcmp(variable, "initial_state")) {
2436 				if(!strcmp(value, "o") || !strcmp(value, "up"))
2437 					temp_host->initial_state = 0; /* HOST_UP */
2438 				else if(!strcmp(value, "d") || !strcmp(value, "down"))
2439 					temp_host->initial_state = 1; /* HOST_DOWN */
2440 				else if(!strcmp(value, "u") || !strcmp(value, "unreachable"))
2441 					temp_host->initial_state = 2; /* HOST_UNREACHABLE */
2442 				else {
2443 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid initial state '%s' in host definition.\n", value);
2444 					result = ERROR;
2445 					}
2446 				temp_host->have_initial_state = TRUE;
2447 				}
2448 			else if(!strcmp(variable, "check_interval") || !strcmp(variable, "normal_check_interval")) {
2449 				if(!strcmp(variable, "normal_check_interval"))
2450 					logit(NSLOG_CONFIG_WARNING, TRUE, "WARNING: The normal_check_interval attribute is deprecated and will be removed in future versions. Please use check_interval instead.\n");
2451 				temp_host->check_interval = strtod(value, NULL);
2452 				temp_host->have_check_interval = TRUE;
2453 				}
2454 			else if(!strcmp(variable, "retry_interval") || !strcmp(variable, "retry_check_interval")) {
2455 				if(!strcmp(variable, "retry_check_interval"))
2456 					logit(NSLOG_CONFIG_WARNING, TRUE, "WARNING: The retry_check_interval attribute is deprecated and will be removed in future versions. Please use retry_interval instead.\n");
2457 				temp_host->retry_interval = strtod(value, NULL);
2458 				temp_host->have_retry_interval = TRUE;
2459 				}
2460 			else if(!strcmp(variable, "importance") ||
2461 					!strcmp(variable, "hourly_value")) {
2462 				if(!strcmp(variable, "hourly_value")) {
2463 					logit(NSLOG_CONFIG_WARNING, TRUE, "WARNING: The hourly_value attribute is deprecated and will be removed in future versions. Please use importance instead.\n");
2464 					}
2465 				temp_host->hourly_value = (unsigned int)strtoul(value, NULL, 10);
2466 				temp_host->have_hourly_value = 1;
2467 				}
2468 			else if(!strcmp(variable, "max_check_attempts")) {
2469 				temp_host->max_check_attempts = atoi(value);
2470 				temp_host->have_max_check_attempts = TRUE;
2471 				}
2472 			else if(!strcmp(variable, "checks_enabled") || !strcmp(variable, "active_checks_enabled")) {
2473 				temp_host->active_checks_enabled = (atoi(value) > 0) ? TRUE : FALSE;
2474 				temp_host->have_active_checks_enabled = TRUE;
2475 				}
2476 			else if(!strcmp(variable, "passive_checks_enabled")) {
2477 				temp_host->passive_checks_enabled = (atoi(value) > 0) ? TRUE : FALSE;
2478 				temp_host->have_passive_checks_enabled = TRUE;
2479 				}
2480 			else if(!strcmp(variable, "event_handler_enabled")) {
2481 				temp_host->event_handler_enabled = (atoi(value) > 0) ? TRUE : FALSE;
2482 				temp_host->have_event_handler_enabled = TRUE;
2483 				}
2484 			else if(!strcmp(variable, "check_freshness")) {
2485 				temp_host->check_freshness = (atoi(value) > 0) ? TRUE : FALSE;
2486 				temp_host->have_check_freshness = TRUE;
2487 				}
2488 			else if(!strcmp(variable, "freshness_threshold")) {
2489 				temp_host->freshness_threshold = atoi(value);
2490 				temp_host->have_freshness_threshold = TRUE;
2491 				}
2492 			else if(!strcmp(variable, "low_flap_threshold")) {
2493 				temp_host->low_flap_threshold = strtod(value, NULL);
2494 				temp_host->have_low_flap_threshold = TRUE;
2495 				}
2496 			else if(!strcmp(variable, "high_flap_threshold")) {
2497 				temp_host->high_flap_threshold = strtod(value, NULL);
2498 				temp_host->have_high_flap_threshold = TRUE;
2499 				}
2500 			else if(!strcmp(variable, "flap_detection_enabled")) {
2501 				temp_host->flap_detection_enabled = (atoi(value) > 0) ? TRUE : FALSE;
2502 				temp_host->have_flap_detection_enabled = TRUE;
2503 				}
2504 			else if(!strcmp(variable, "flap_detection_options")) {
2505 
2506 				/* user is specifying something, so discard defaults... */
2507 				temp_host->flap_detection_options = OPT_NOTHING;
2508 
2509 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
2510 					if(!strcmp(temp_ptr, "o") || !strcmp(temp_ptr, "up"))
2511 						flag_set(temp_host->flap_detection_options, OPT_UP);
2512 					else if(!strcmp(temp_ptr, "d") || !strcmp(temp_ptr, "down"))
2513 						flag_set(temp_host->flap_detection_options, OPT_DOWN);
2514 					else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unreachable"))
2515 						flag_set(temp_host->flap_detection_options, OPT_UNREACHABLE);
2516 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
2517 						temp_host->flap_detection_options = OPT_NOTHING;
2518 						}
2519 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
2520 						temp_host->flap_detection_options = OPT_ALL;
2521 						}
2522 					else {
2523 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid flap detection option '%s' in host definition.\n", temp_ptr);
2524 						result = ERROR;
2525 						}
2526 					}
2527 				temp_host->have_flap_detection_options = TRUE;
2528 				}
2529 			else if(!strcmp(variable, "notification_options")) {
2530 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
2531 					if(!strcmp(temp_ptr, "d") || !strcmp(temp_ptr, "down"))
2532 						flag_set(temp_host->notification_options, OPT_DOWN);
2533 					else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unreachable"))
2534 						flag_set(temp_host->notification_options, OPT_UNREACHABLE);
2535 					else if(!strcmp(temp_ptr, "r") || !strcmp(temp_ptr, "recovery"))
2536 						flag_set(temp_host->notification_options, OPT_RECOVERY);
2537 					else if(!strcmp(temp_ptr, "f") || !strcmp(temp_ptr, "flapping"))
2538 						flag_set(temp_host->notification_options, OPT_FLAPPING);
2539 					else if(!strcmp(temp_ptr, "s") || !strcmp(temp_ptr, "downtime"))
2540 						flag_set(temp_host->notification_options, OPT_DOWNTIME);
2541 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
2542 						temp_host->notification_options = OPT_NOTHING;
2543 						}
2544 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
2545 						temp_host->notification_options = OPT_ALL;
2546 						}
2547 					else {
2548 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid notification option '%s' in host definition.\n", temp_ptr);
2549 						result = ERROR;
2550 						}
2551 					}
2552 				temp_host->have_notification_options = TRUE;
2553 				}
2554 			else if(!strcmp(variable, "notifications_enabled")) {
2555 				temp_host->notifications_enabled = (atoi(value) > 0) ? TRUE : FALSE;
2556 				temp_host->have_notifications_enabled = TRUE;
2557 				}
2558 			else if(!strcmp(variable, "notification_interval")) {
2559 				temp_host->notification_interval = strtod(value, NULL);
2560 				temp_host->have_notification_interval = TRUE;
2561 				}
2562 			else if(!strcmp(variable, "first_notification_delay")) {
2563 				temp_host->first_notification_delay = strtod(value, NULL);
2564 				temp_host->have_first_notification_delay = TRUE;
2565 				}
2566 			else if(!strcmp(variable, "stalking_options")) {
2567 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
2568 					if(!strcmp(temp_ptr, "o") || !strcmp(temp_ptr, "up"))
2569 						flag_set(temp_host->stalking_options, OPT_UP);
2570 					else if(!strcmp(temp_ptr, "d") || !strcmp(temp_ptr, "down"))
2571 						flag_set(temp_host->stalking_options, OPT_DOWN);
2572 					else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unreachable"))
2573 						flag_set(temp_host->stalking_options, OPT_UNREACHABLE);
2574 					else if(!strcmp(temp_ptr, "N") || !strcmp(temp_ptr, "notifications"))
2575 						flag_set(temp_host->stalking_options, OPT_NOTIFICATIONS);
2576 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
2577 						temp_host->stalking_options = OPT_NOTHING;
2578 						}
2579 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
2580 						temp_host->stalking_options = OPT_ALL;
2581 						}
2582 					else {
2583 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid stalking option '%s' in host definition.\n", temp_ptr);
2584 						result = ERROR;
2585 						}
2586 					}
2587 				temp_host->have_stalking_options = TRUE;
2588 				}
2589 			else if(!strcmp(variable, "process_perf_data")) {
2590 				temp_host->process_perf_data = (atoi(value) > 0) ? TRUE : FALSE;
2591 				temp_host->have_process_perf_data = TRUE;
2592 				}
2593 			else if(!strcmp(variable, "failure_prediction_enabled")) {
2594 				xodtemplate_obsoleted(variable, temp_host->_start_line);
2595 				}
2596 			else if(!strcmp(variable, "2d_coords")) {
2597 				if((temp_ptr = strtok(value, ", ")) == NULL) {
2598 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 2d_coords value '%s' in host definition.\n", temp_ptr);
2599 					return ERROR;
2600 					}
2601 				temp_host->x_2d = atoi(temp_ptr);
2602 				if((temp_ptr = strtok(NULL, ", ")) == NULL) {
2603 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 2d_coords value '%s' in host definition.\n", temp_ptr);
2604 					return ERROR;
2605 					}
2606 				temp_host->y_2d = atoi(temp_ptr);
2607 				temp_host->have_2d_coords = TRUE;
2608 				}
2609 			else if(!strcmp(variable, "3d_coords")) {
2610 				if((temp_ptr = strtok(value, ", ")) == NULL) {
2611 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 3d_coords value '%s' in host definition.\n", temp_ptr);
2612 					return ERROR;
2613 					}
2614 				temp_host->x_3d = strtod(temp_ptr, NULL);
2615 				if((temp_ptr = strtok(NULL, ", ")) == NULL) {
2616 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 3d_coords value '%s' in host definition.\n", temp_ptr);
2617 					return ERROR;
2618 					}
2619 				temp_host->y_3d = strtod(temp_ptr, NULL);
2620 				if((temp_ptr = strtok(NULL, ", ")) == NULL) {
2621 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 3d_coords value '%s' in host definition.\n", temp_ptr);
2622 					return ERROR;
2623 					}
2624 				temp_host->z_3d = strtod(temp_ptr, NULL);
2625 				temp_host->have_3d_coords = TRUE;
2626 				}
2627 			else if(!strcmp(variable, "obsess_over_host") || !strcmp(variable, "obsess")) {
2628 				temp_host->obsess = (atoi(value) > 0) ? TRUE : FALSE;
2629 				temp_host->have_obsess = TRUE;
2630 				}
2631 			else if(!strcmp(variable, "retain_status_information")) {
2632 				temp_host->retain_status_information = (atoi(value) > 0) ? TRUE : FALSE;
2633 				temp_host->have_retain_status_information = TRUE;
2634 				}
2635 			else if(!strcmp(variable, "retain_nonstatus_information")) {
2636 				temp_host->retain_nonstatus_information = (atoi(value) > 0) ? TRUE : FALSE;
2637 				temp_host->have_retain_nonstatus_information = TRUE;
2638 				}
2639 			else if(!strcmp(variable, "register"))
2640 				temp_host->register_object = (atoi(value) > 0) ? TRUE : FALSE;
2641 			else if(variable[0] == '_') {
2642 
2643 				/* get the variable name */
2644 				customvarname = (char *)strdup(variable + 1);
2645 
2646 				/* make sure we have a variable name */
2647 				if(customvarname == NULL || !strcmp(customvarname, "")) {
2648 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Null custom variable name.\n");
2649 					my_free(customvarname);
2650 					return ERROR;
2651 					}
2652 
2653 				/* get the variable value */
2654 				customvarvalue = NULL;
2655 				if(*value && strcmp(value, XODTEMPLATE_NULL))
2656 					customvarvalue = (char *)strdup(value);
2657 
2658 				/* add the custom variable */
2659 				if(xodtemplate_add_custom_variable_to_host(temp_host, customvarname, customvarvalue) == NULL) {
2660 					my_free(customvarname);
2661 					my_free(customvarvalue);
2662 					return ERROR;
2663 					}
2664 
2665 				/* free memory */
2666 				my_free(customvarname);
2667 				my_free(customvarvalue);
2668 				}
2669 			else {
2670 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid host object directive '%s'.\n", variable);
2671 				return ERROR;
2672 				}
2673 
2674 			break;
2675 
2676 		case XODTEMPLATE_SERVICE:
2677 
2678 			temp_service = (xodtemplate_service *)xodtemplate_current_object;
2679 
2680 			if(!strcmp(variable, "use")) {
2681 				if((temp_service->template = (char *)strdup(value)) == NULL)
2682 					result = ERROR;
2683 				}
2684 			else if(!strcmp(variable, "name")) {
2685 
2686 				if((temp_service->name = (char *)strdup(value)) == NULL)
2687 					result = ERROR;
2688 
2689 				if(result == OK) {
2690 					/* add service to template skiplist for fast searches */
2691 					result = skiplist_insert(xobject_template_skiplists[SERVICE_SKIPLIST], (void *)temp_service);
2692 					switch(result) {
2693 						case SKIPLIST_ERROR_DUPLICATE:
2694 							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);
2695 							result = ERROR;
2696 							break;
2697 						case SKIPLIST_OK:
2698 							result = OK;
2699 							break;
2700 						default:
2701 							result = ERROR;
2702 							break;
2703 						}
2704 					}
2705 				}
2706 			else if(!strcmp(variable, "host") || !strcmp(variable, "hosts") || !strcmp(variable, "host_name")) {
2707 				if(strcmp(value, XODTEMPLATE_NULL)) {
2708 					if((temp_service->host_name = (char *)strdup(value)) == NULL)
2709 						result = ERROR;
2710 					}
2711 				temp_service->have_host_name = TRUE;
2712 
2713 				/* NOTE: services are added to the skiplist in xodtemplate_duplicate_services(), except if daemon is using precached config */
2714 				if(result == OK && force_skiplists == TRUE  && temp_service->host_name != NULL && temp_service->service_description != NULL) {
2715 					/* add service to template skiplist for fast searches */
2716 					result = skiplist_insert(xobject_skiplists[SERVICE_SKIPLIST], (void *)temp_service);
2717 					switch(result) {
2718 						case SKIPLIST_ERROR_DUPLICATE:
2719 							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);
2720 							result = ERROR;
2721 							break;
2722 						case SKIPLIST_OK:
2723 							result = OK;
2724 							temp_service->id = xodcount.services++;
2725 							break;
2726 						default:
2727 							result = ERROR;
2728 							break;
2729 						}
2730 					}
2731 				}
2732 			else if(!strcmp(variable, "service_description") || !strcmp(variable, "description")) {
2733 				if(strcmp(value, XODTEMPLATE_NULL)) {
2734 					if((temp_service->service_description = (char *)strdup(value)) == NULL)
2735 						result = ERROR;
2736 					}
2737 				temp_service->have_service_description = TRUE;
2738 
2739 				/* NOTE: services are added to the skiplist in xodtemplate_duplicate_services(), except if daemon is using precached config */
2740 				if(result == OK && force_skiplists == TRUE  && temp_service->host_name != NULL && temp_service->service_description != NULL) {
2741 					/* add service to template skiplist for fast searches */
2742 					result = skiplist_insert(xobject_skiplists[SERVICE_SKIPLIST], (void *)temp_service);
2743 					switch(result) {
2744 						case SKIPLIST_ERROR_DUPLICATE:
2745 							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);
2746 							result = ERROR;
2747 							break;
2748 						case SKIPLIST_OK:
2749 							result = OK;
2750 							temp_service->id = xodcount.services++;
2751 							break;
2752 						default:
2753 							result = ERROR;
2754 							break;
2755 						}
2756 					}
2757 				}
2758 			else if(!strcmp(variable, "display_name")) {
2759 				if(strcmp(value, XODTEMPLATE_NULL)) {
2760 					if((temp_service->display_name = (char *)strdup(value)) == NULL)
2761 						result = ERROR;
2762 					}
2763 				temp_service->have_display_name = TRUE;
2764 				}
2765 			else if(!strcmp(variable, "parents")) {
2766 				if(strcmp(value, XODTEMPLATE_NULL)) {
2767 					if((temp_service->parents = (char *)strdup(value)) == NULL)
2768 						result = ERROR;
2769 					}
2770 				temp_service->have_parents = TRUE;
2771 				}
2772 			else if(!strcmp(variable, "hostgroup") || !strcmp(variable, "hostgroups") || !strcmp(variable, "hostgroup_name")) {
2773 				if(strcmp(value, XODTEMPLATE_NULL)) {
2774 					if((temp_service->hostgroup_name = (char *)strdup(value)) == NULL)
2775 						result = ERROR;
2776 					}
2777 				temp_service->have_hostgroup_name = TRUE;
2778 				}
2779 			else if(!strcmp(variable, "service_groups") || !strcmp(variable, "servicegroups")) {
2780 				if(strcmp(value, XODTEMPLATE_NULL)) {
2781 					if((temp_service->service_groups = (char *)strdup(value)) == NULL)
2782 						result = ERROR;
2783 					}
2784 				temp_service->have_service_groups = TRUE;
2785 				}
2786 			else if(!strcmp(variable, "check_command")) {
2787 				if(strcmp(value, XODTEMPLATE_NULL)) {
2788 					if(value[0] == '!') {
2789 						temp_service->have_important_check_command = TRUE;
2790 						temp_ptr = value + 1;
2791 						}
2792 					else
2793 						temp_ptr = value;
2794 					if((temp_service->check_command = (char *)strdup(temp_ptr)) == NULL)
2795 						result = ERROR;
2796 					}
2797 				temp_service->have_check_command = TRUE;
2798 				}
2799 			else if(!strcmp(variable, "check_period")) {
2800 				if(strcmp(value, XODTEMPLATE_NULL)) {
2801 					if((temp_service->check_period = (char *)strdup(value)) == NULL)
2802 						result = ERROR;
2803 					}
2804 				temp_service->have_check_period = TRUE;
2805 				}
2806 			else if(!strcmp(variable, "event_handler")) {
2807 				if(strcmp(value, XODTEMPLATE_NULL)) {
2808 					if((temp_service->event_handler = (char *)strdup(value)) == NULL)
2809 						result = ERROR;
2810 					}
2811 				temp_service->have_event_handler = TRUE;
2812 				}
2813 			else if(!strcmp(variable, "notification_period")) {
2814 				if(strcmp(value, XODTEMPLATE_NULL)) {
2815 					if((temp_service->notification_period = (char *)strdup(value)) == NULL)
2816 						result = ERROR;
2817 					}
2818 				temp_service->have_notification_period = TRUE;
2819 				}
2820 			else if(!strcmp(variable, "contact_groups")) {
2821 				if (*value == '\0') {
2822 					logit(NSLOG_CONFIG_WARNING, TRUE, "Error: Empty value for contact_groups (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_service->_config_file), temp_service->_start_line);
2823 					result = ERROR;
2824 					break;
2825 				}
2826 				if(strcmp(value, XODTEMPLATE_NULL)) {
2827 					if((temp_service->contact_groups = (char *)strdup(value)) == NULL)
2828 						result = ERROR;
2829 					}
2830 				temp_service->have_contact_groups = TRUE;
2831 				}
2832 			else if(!strcmp(variable, "contacts")) {
2833 				if (*value == '\0') {
2834 					logit(NSLOG_CONFIG_WARNING, TRUE, "Error: Empty value for contacts (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_service->_config_file), temp_service->_start_line);
2835 					result = ERROR;
2836 					break;
2837 				}
2838 				if(strcmp(value, XODTEMPLATE_NULL)) {
2839 					if((temp_service->contacts = (char *)strdup(value)) == NULL)
2840 						result = ERROR;
2841 					}
2842 				temp_service->have_contacts = TRUE;
2843 				}
2844 			else if(!strcmp(variable, "failure_prediction_options")) {
2845 				xodtemplate_obsoleted(variable, temp_service->_start_line);
2846 				}
2847 			else if(!strcmp(variable, "notes")) {
2848 				if(strcmp(value, XODTEMPLATE_NULL)) {
2849 					if((temp_service->notes = (char *)strdup(value)) == NULL)
2850 						result = ERROR;
2851 					}
2852 				temp_service->have_notes = TRUE;
2853 				}
2854 			else if(!strcmp(variable, "notes_url")) {
2855 				if(strcmp(value, XODTEMPLATE_NULL)) {
2856 					if((temp_service->notes_url = (char *)strdup(value)) == NULL)
2857 						result = ERROR;
2858 					}
2859 				temp_service->have_notes_url = TRUE;
2860 				}
2861 			else if(!strcmp(variable, "action_url")) {
2862 				if(strcmp(value, XODTEMPLATE_NULL)) {
2863 					if((temp_service->action_url = (char *)strdup(value)) == NULL)
2864 						result = ERROR;
2865 					}
2866 				temp_service->have_action_url = TRUE;
2867 				}
2868 			else if(!strcmp(variable, "icon_image")) {
2869 				if(strcmp(value, XODTEMPLATE_NULL)) {
2870 					if((temp_service->icon_image = (char *)strdup(value)) == NULL)
2871 						result = ERROR;
2872 					}
2873 				temp_service->have_icon_image = TRUE;
2874 				}
2875 			else if(!strcmp(variable, "icon_image_alt")) {
2876 				if(strcmp(value, XODTEMPLATE_NULL)) {
2877 					if((temp_service->icon_image_alt = (char *)strdup(value)) == NULL)
2878 						result = ERROR;
2879 					}
2880 				temp_service->have_icon_image_alt = TRUE;
2881 				}
2882 			else if(!strcmp(variable, "initial_state")) {
2883 				if(!strcmp(value, "o") || !strcmp(value, "ok"))
2884 					temp_service->initial_state = STATE_OK;
2885 				else if(!strcmp(value, "w") || !strcmp(value, "warning"))
2886 					temp_service->initial_state = STATE_WARNING;
2887 				else if(!strcmp(value, "u") || !strcmp(value, "unknown"))
2888 					temp_service->initial_state = STATE_UNKNOWN;
2889 				else if(!strcmp(value, "c") || !strcmp(value, "critical"))
2890 					temp_service->initial_state = STATE_CRITICAL;
2891 				else {
2892 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid initial state '%s' in service definition.\n", value);
2893 					result = ERROR;
2894 					}
2895 				temp_service->have_initial_state = TRUE;
2896 				}
2897 			else if(!strcmp(variable, "importance") ||
2898 					!strcmp(variable, "hourly_value")) {
2899 				if(!strcmp(variable, "hourly_value")) {
2900 					logit(NSLOG_CONFIG_WARNING, TRUE, "WARNING: The hourly_value attribute is deprecated and will be removed in future versions. Please use importance instead.\n");
2901 					}
2902 				temp_service->hourly_value = (unsigned int)strtoul(value, NULL, 10);
2903 				temp_service->have_hourly_value = 1;
2904 				}
2905 			else if(!strcmp(variable, "max_check_attempts")) {
2906 				temp_service->max_check_attempts = atoi(value);
2907 				temp_service->have_max_check_attempts = TRUE;
2908 				}
2909 			else if(!strcmp(variable, "check_interval") || !strcmp(variable, "normal_check_interval")) {
2910 				if(!strcmp(variable, "normal_check_interval"))
2911 					logit(NSLOG_CONFIG_WARNING, TRUE, "WARNING: The normal_check_interval attribute is deprecated and will be removed in future versions. Please use check_interval instead.\n");
2912 				temp_service->check_interval = strtod(value, NULL);
2913 				temp_service->have_check_interval = TRUE;
2914 				}
2915 			else if(!strcmp(variable, "retry_interval") || !strcmp(variable, "retry_check_interval")) {
2916 				if(!strcmp(variable, "retry_check_interval"))
2917 					logit(NSLOG_CONFIG_WARNING, TRUE, "WARNING: The retry_check_interval attribute is deprecated and will be removed in future versions. Please use retry_interval instead.\n");
2918 				temp_service->retry_interval = strtod(value, NULL);
2919 				temp_service->have_retry_interval = TRUE;
2920 				}
2921 			else if(!strcmp(variable, "active_checks_enabled")) {
2922 				temp_service->active_checks_enabled = (atoi(value) > 0) ? TRUE : FALSE;
2923 				temp_service->have_active_checks_enabled = TRUE;
2924 				}
2925 			else if(!strcmp(variable, "passive_checks_enabled")) {
2926 				temp_service->passive_checks_enabled = (atoi(value) > 0) ? TRUE : FALSE;
2927 				temp_service->have_passive_checks_enabled = TRUE;
2928 				}
2929 			else if(!strcmp(variable, "parallelize_check")) {
2930 				temp_service->parallelize_check = atoi(value);
2931 				temp_service->have_parallelize_check = TRUE;
2932 				}
2933 			else if(!strcmp(variable, "is_volatile")) {
2934 				temp_service->is_volatile = (atoi(value) > 0) ? TRUE : FALSE;
2935 				temp_service->have_is_volatile = TRUE;
2936 				}
2937 			else if(!strcmp(variable, "obsess_over_service") || !strcmp(variable, "obsess")) {
2938 				temp_service->obsess = (atoi(value) > 0) ? TRUE : FALSE;
2939 				temp_service->have_obsess = TRUE;
2940 				}
2941 			else if(!strcmp(variable, "event_handler_enabled")) {
2942 				temp_service->event_handler_enabled = (atoi(value) > 0) ? TRUE : FALSE;
2943 				temp_service->have_event_handler_enabled = TRUE;
2944 				}
2945 			else if(!strcmp(variable, "check_freshness")) {
2946 				temp_service->check_freshness = (atoi(value) > 0) ? TRUE : FALSE;
2947 				temp_service->have_check_freshness = TRUE;
2948 				}
2949 			else if(!strcmp(variable, "freshness_threshold")) {
2950 				temp_service->freshness_threshold = atoi(value);
2951 				temp_service->have_freshness_threshold = TRUE;
2952 				}
2953 			else if(!strcmp(variable, "low_flap_threshold")) {
2954 				temp_service->low_flap_threshold = strtod(value, NULL);
2955 				temp_service->have_low_flap_threshold = TRUE;
2956 				}
2957 			else if(!strcmp(variable, "high_flap_threshold")) {
2958 				temp_service->high_flap_threshold = strtod(value, NULL);
2959 				temp_service->have_high_flap_threshold = TRUE;
2960 				}
2961 			else if(!strcmp(variable, "flap_detection_enabled")) {
2962 				temp_service->flap_detection_enabled = (atoi(value) > 0) ? TRUE : FALSE;
2963 				temp_service->have_flap_detection_enabled = TRUE;
2964 				}
2965 			else if(!strcmp(variable, "flap_detection_options")) {
2966 
2967 				/* user is specifying something, so discard defaults... */
2968 				temp_service->flap_detection_options = OPT_NOTHING;
2969 
2970 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
2971 					if(!strcmp(temp_ptr, "o") || !strcmp(temp_ptr, "ok"))
2972 						flag_set(temp_service->flap_detection_options, OPT_OK);
2973 					else if(!strcmp(temp_ptr, "w") || !strcmp(temp_ptr, "warning"))
2974 						flag_set(temp_service->flap_detection_options, OPT_WARNING);
2975 					else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unknown"))
2976 						flag_set(temp_service->flap_detection_options, OPT_UNKNOWN);
2977 					else if(!strcmp(temp_ptr, "c") || !strcmp(temp_ptr, "critical"))
2978 						flag_set(temp_service->flap_detection_options, OPT_CRITICAL);
2979 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
2980 						temp_service->flap_detection_options = OPT_NOTHING;
2981 						}
2982 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
2983 						temp_service->flap_detection_options = OPT_ALL;
2984 						}
2985 					else {
2986 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid flap detection option '%s' in service definition.\n", temp_ptr);
2987 						return ERROR;
2988 						}
2989 					}
2990 				temp_service->have_flap_detection_options = TRUE;
2991 				}
2992 			else if(!strcmp(variable, "notification_options")) {
2993 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
2994 					if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unknown"))
2995 						flag_set(temp_service->notification_options, OPT_UNKNOWN);
2996 					else if(!strcmp(temp_ptr, "w") || !strcmp(temp_ptr, "warning"))
2997 						flag_set(temp_service->notification_options, OPT_WARNING);
2998 					else if(!strcmp(temp_ptr, "c") || !strcmp(temp_ptr, "critical"))
2999 						flag_set(temp_service->notification_options, OPT_CRITICAL);
3000 					else if(!strcmp(temp_ptr, "r") || !strcmp(temp_ptr, "recovery"))
3001 						flag_set(temp_service->notification_options, OPT_RECOVERY);
3002 					else if(!strcmp(temp_ptr, "f") || !strcmp(temp_ptr, "flapping"))
3003 						flag_set(temp_service->notification_options, OPT_FLAPPING);
3004 					else if(!strcmp(temp_ptr, "s") || !strcmp(temp_ptr, "downtime"))
3005 						flag_set(temp_service->notification_options, OPT_DOWNTIME);
3006 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
3007 						temp_service->notification_options = OPT_NOTHING;
3008 						}
3009 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
3010 						temp_service->notification_options = OPT_ALL;
3011 						}
3012 					else {
3013 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid notification option '%s' in service definition.\n", temp_ptr);
3014 						return ERROR;
3015 						}
3016 					}
3017 				temp_service->have_notification_options = TRUE;
3018 				}
3019 			else if(!strcmp(variable, "notifications_enabled")) {
3020 				temp_service->notifications_enabled = (atoi(value) > 0) ? TRUE : FALSE;
3021 				temp_service->have_notifications_enabled = TRUE;
3022 				}
3023 			else if(!strcmp(variable, "notification_interval")) {
3024 				temp_service->notification_interval = strtod(value, NULL);
3025 				temp_service->have_notification_interval = TRUE;
3026 				}
3027 			else if(!strcmp(variable, "first_notification_delay")) {
3028 				temp_service->first_notification_delay = strtod(value, NULL);
3029 				temp_service->have_first_notification_delay = TRUE;
3030 				}
3031 			else if(!strcmp(variable, "stalking_options")) {
3032 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
3033 					if(!strcmp(temp_ptr, "o") || !strcmp(temp_ptr, "ok"))
3034 						flag_set(temp_service->stalking_options, OPT_OK);
3035 					else if(!strcmp(temp_ptr, "w") || !strcmp(temp_ptr, "warning"))
3036 						flag_set(temp_service->stalking_options, OPT_WARNING);
3037 					else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unknown"))
3038 						flag_set(temp_service->stalking_options, OPT_UNKNOWN);
3039 					else if(!strcmp(temp_ptr, "c") || !strcmp(temp_ptr, "critical"))
3040 						flag_set(temp_service->stalking_options, OPT_CRITICAL);
3041 					else if(!strcmp(temp_ptr, "N") || !strcmp(temp_ptr, "notifications"))
3042 						flag_set(temp_service->stalking_options, OPT_NOTIFICATIONS);
3043 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
3044 						temp_service->stalking_options = OPT_NOTHING;
3045 						}
3046 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
3047 						temp_service->stalking_options = OPT_ALL;
3048 						}
3049 					else {
3050 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid stalking option '%s' in service definition.\n", temp_ptr);
3051 						return ERROR;
3052 						}
3053 					}
3054 				temp_service->have_stalking_options = TRUE;
3055 				}
3056 			else if(!strcmp(variable, "process_perf_data")) {
3057 				temp_service->process_perf_data = (atoi(value) > 0) ? TRUE : FALSE;
3058 				temp_service->have_process_perf_data = TRUE;
3059 				}
3060 			else if(!strcmp(variable, "failure_prediction_enabled")) {
3061 				xodtemplate_obsoleted(variable, temp_service->_start_line);
3062 				}
3063 			else if(!strcmp(variable, "retain_status_information")) {
3064 				temp_service->retain_status_information = (atoi(value) > 0) ? TRUE : FALSE;
3065 				temp_service->have_retain_status_information = TRUE;
3066 				}
3067 			else if(!strcmp(variable, "retain_nonstatus_information")) {
3068 				temp_service->retain_nonstatus_information = (atoi(value) > 0) ? TRUE : FALSE;
3069 				temp_service->have_retain_nonstatus_information = TRUE;
3070 				}
3071 			else if(!strcmp(variable, "register"))
3072 				temp_service->register_object = (atoi(value) > 0) ? TRUE : FALSE;
3073 			else if(variable[0] == '_') {
3074 
3075 				/* get the variable name */
3076 				customvarname = (char *)strdup(variable + 1);
3077 
3078 				/* make sure we have a variable name */
3079 				if(customvarname == NULL || !strcmp(customvarname, "")) {
3080 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Null custom variable name.\n");
3081 					my_free(customvarname);
3082 					return ERROR;
3083 					}
3084 
3085 				/* get the variable value */
3086 				if(*value && strcmp(value, XODTEMPLATE_NULL))
3087 					customvarvalue = (char *)strdup(value);
3088 				else
3089 					customvarvalue = NULL;
3090 
3091 				/* add the custom variable */
3092 				if(xodtemplate_add_custom_variable_to_service(temp_service, customvarname, customvarvalue) == NULL) {
3093 					my_free(customvarname);
3094 					my_free(customvarvalue);
3095 					return ERROR;
3096 					}
3097 
3098 				/* free memory */
3099 				my_free(customvarname);
3100 				my_free(customvarvalue);
3101 				}
3102 			else {
3103 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid service object directive '%s'.\n", variable);
3104 				return ERROR;
3105 				}
3106 
3107 			break;
3108 
3109 		case XODTEMPLATE_HOSTDEPENDENCY:
3110 
3111 			temp_hostdependency = (xodtemplate_hostdependency *)xodtemplate_current_object;
3112 
3113 			if(!strcmp(variable, "use")) {
3114 				if((temp_hostdependency->template = (char *)strdup(value)) == NULL)
3115 					result = ERROR;
3116 				}
3117 			else if(!strcmp(variable, "name")) {
3118 
3119 				if((temp_hostdependency->name = (char *)strdup(value)) == NULL)
3120 					result = ERROR;
3121 
3122 				if(result == OK) {
3123 					/* add dependency to template skiplist for fast searches */
3124 					result = skiplist_insert(xobject_template_skiplists[HOSTDEPENDENCY_SKIPLIST], (void *)temp_hostdependency);
3125 					switch(result) {
3126 						case SKIPLIST_ERROR_DUPLICATE:
3127 							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);
3128 							result = ERROR;
3129 							break;
3130 						case SKIPLIST_OK:
3131 							result = OK;
3132 							break;
3133 						default:
3134 							result = ERROR;
3135 							break;
3136 						}
3137 					}
3138 				}
3139 			else if(!strcmp(variable, "hostgroup") || !strcmp(variable, "hostgroups") || !strcmp(variable, "hostgroup_name")) {
3140 				if(strcmp(value, XODTEMPLATE_NULL)) {
3141 					if((temp_hostdependency->hostgroup_name = (char *)strdup(value)) == NULL)
3142 						result = ERROR;
3143 					}
3144 				temp_hostdependency->have_hostgroup_name = TRUE;
3145 				}
3146 			else if(!strcmp(variable, "host") || !strcmp(variable, "host_name") || !strcmp(variable, "master_host") || !strcmp(variable, "master_host_name")) {
3147 				if(strcmp(value, XODTEMPLATE_NULL)) {
3148 					if((temp_hostdependency->host_name = (char *)strdup(value)) == NULL)
3149 						result = ERROR;
3150 					}
3151 				temp_hostdependency->have_host_name = TRUE;
3152 				}
3153 			else if(!strcmp(variable, "dependent_hostgroup") || !strcmp(variable, "dependent_hostgroups") || !strcmp(variable, "dependent_hostgroup_name")) {
3154 				if(strcmp(value, XODTEMPLATE_NULL)) {
3155 					if((temp_hostdependency->dependent_hostgroup_name = (char *)strdup(value)) == NULL)
3156 						result = ERROR;
3157 					}
3158 				temp_hostdependency->have_dependent_hostgroup_name = TRUE;
3159 				}
3160 			else if(!strcmp(variable, "dependent_host") || !strcmp(variable, "dependent_host_name")) {
3161 				if(strcmp(value, XODTEMPLATE_NULL)) {
3162 					if((temp_hostdependency->dependent_host_name = (char *)strdup(value)) == NULL)
3163 						result = ERROR;
3164 					}
3165 				temp_hostdependency->have_dependent_host_name = TRUE;
3166 				}
3167 			else if(!strcmp(variable, "dependency_period")) {
3168 				if(strcmp(value, XODTEMPLATE_NULL)) {
3169 					if((temp_hostdependency->dependency_period = (char *)strdup(value)) == NULL)
3170 						result = ERROR;
3171 					}
3172 				temp_hostdependency->have_dependency_period = TRUE;
3173 				}
3174 			else if(!strcmp(variable, "inherits_parent")) {
3175 				temp_hostdependency->inherits_parent = (atoi(value) > 0) ? TRUE : FALSE;
3176 				temp_hostdependency->have_inherits_parent = TRUE;
3177 				}
3178 			else if(!strcmp(variable, "notification_failure_options") || !strcmp(variable, "notification_failure_criteria")) {
3179 				temp_hostdependency->have_notification_failure_options = TRUE;
3180 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
3181 					if(!strcmp(temp_ptr, "o") || !strcmp(temp_ptr, "up"))
3182 						flag_set(temp_hostdependency->notification_failure_options, OPT_UP);
3183 					else if(!strcmp(temp_ptr, "d") || !strcmp(temp_ptr, "down"))
3184 						flag_set(temp_hostdependency->notification_failure_options, OPT_DOWN);
3185 					else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unreachable"))
3186 						flag_set(temp_hostdependency->notification_failure_options, OPT_UNREACHABLE);
3187 					else if(!strcmp(temp_ptr, "p") || !strcmp(temp_ptr, "pending"))
3188 						flag_set(temp_hostdependency->notification_failure_options, OPT_PENDING);
3189 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
3190 						temp_hostdependency->notification_failure_options = OPT_NOTHING;
3191 						temp_hostdependency->have_notification_failure_options = FALSE;
3192 						}
3193 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
3194 						temp_hostdependency->notification_failure_options = OPT_ALL;
3195 						}
3196 					else {
3197 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid notification dependency option '%s' in hostdependency definition.\n", temp_ptr);
3198 						return ERROR;
3199 						}
3200 					}
3201 				}
3202 			else if(!strcmp(variable, "execution_failure_options") || !strcmp(variable, "execution_failure_criteria")) {
3203 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
3204 					if(!strcmp(temp_ptr, "o") || !strcmp(temp_ptr, "up"))
3205 						flag_set(temp_hostdependency->execution_failure_options, OPT_UP);
3206 					else if(!strcmp(temp_ptr, "d") || !strcmp(temp_ptr, "down"))
3207 						flag_set(temp_hostdependency->execution_failure_options, OPT_DOWN);
3208 					else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unreachable"))
3209 						flag_set(temp_hostdependency->execution_failure_options, OPT_UNREACHABLE);
3210 					else if(!strcmp(temp_ptr, "p") || !strcmp(temp_ptr, "pending"))
3211 						flag_set(temp_hostdependency->execution_failure_options, OPT_PENDING);
3212 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
3213 						temp_hostdependency->execution_failure_options = OPT_NOTHING;
3214 						}
3215 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
3216 						temp_hostdependency->execution_failure_options = OPT_ALL;
3217 						}
3218 					else {
3219 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid execution dependency option '%s' in hostdependency definition.\n", temp_ptr);
3220 						return ERROR;
3221 						}
3222 					}
3223 				temp_hostdependency->have_execution_failure_options = TRUE;
3224 				}
3225 			else if(!strcmp(variable, "register"))
3226 				temp_hostdependency->register_object = (atoi(value) > 0) ? TRUE : FALSE;
3227 			else {
3228 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid hostdependency object directive '%s'.\n", variable);
3229 				return ERROR;
3230 				}
3231 
3232 			break;
3233 
3234 
3235 		case XODTEMPLATE_HOSTESCALATION:
3236 
3237 			temp_hostescalation = (xodtemplate_hostescalation *)xodtemplate_current_object;
3238 
3239 			if(!strcmp(variable, "use")) {
3240 				if((temp_hostescalation->template = (char *)strdup(value)) == NULL)
3241 					result = ERROR;
3242 				}
3243 			else if(!strcmp(variable, "name")) {
3244 
3245 				if((temp_hostescalation->name = (char *)strdup(value)) == NULL)
3246 					result = ERROR;
3247 
3248 				if(result == OK) {
3249 					/* add escalation to template skiplist for fast searches */
3250 					result = skiplist_insert(xobject_template_skiplists[HOSTESCALATION_SKIPLIST], (void *)temp_hostescalation);
3251 					switch(result) {
3252 						case SKIPLIST_ERROR_DUPLICATE:
3253 							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);
3254 							result = ERROR;
3255 							break;
3256 						case SKIPLIST_OK:
3257 							result = OK;
3258 							break;
3259 						default:
3260 							result = ERROR;
3261 							break;
3262 						}
3263 					}
3264 				}
3265 			else if(!strcmp(variable, "hostgroup") || !strcmp(variable, "hostgroups") || !strcmp(variable, "hostgroup_name")) {
3266 				if(strcmp(value, XODTEMPLATE_NULL)) {
3267 					if((temp_hostescalation->hostgroup_name = (char *)strdup(value)) == NULL)
3268 						result = ERROR;
3269 					}
3270 				temp_hostescalation->have_hostgroup_name = TRUE;
3271 				}
3272 			else if(!strcmp(variable, "host") || !strcmp(variable, "host_name")) {
3273 				if(strcmp(value, XODTEMPLATE_NULL)) {
3274 					if((temp_hostescalation->host_name = (char *)strdup(value)) == NULL)
3275 						result = ERROR;
3276 					}
3277 				temp_hostescalation->have_host_name = TRUE;
3278 				}
3279 			else if(!strcmp(variable, "contact_groups")) {
3280 				if (*value == '\0') {
3281 					logit(NSLOG_CONFIG_WARNING, TRUE, "Error: Empty value for contact_groups (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_hostescalation->_config_file), temp_hostescalation->_start_line);
3282 					result = ERROR;
3283 					break;
3284 				}
3285 				if(strcmp(value, XODTEMPLATE_NULL)) {
3286 					if((temp_hostescalation->contact_groups = (char *)strdup(value)) == NULL)
3287 						result = ERROR;
3288 					}
3289 				temp_hostescalation->have_contact_groups = TRUE;
3290 				}
3291 			else if(!strcmp(variable, "contacts")) {
3292 				if (*value == '\0') {
3293 					logit(NSLOG_CONFIG_WARNING, TRUE, "Error: Empty value for contacts (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_hostescalation->_config_file), temp_hostescalation->_start_line);
3294 					result = ERROR;
3295 					break;
3296 				}
3297 				if(strcmp(value, XODTEMPLATE_NULL)) {
3298 					if((temp_hostescalation->contacts = (char *)strdup(value)) == NULL)
3299 						result = ERROR;
3300 					}
3301 				temp_hostescalation->have_contacts = TRUE;
3302 				}
3303 			else if(!strcmp(variable, "escalation_period")) {
3304 				if(strcmp(value, XODTEMPLATE_NULL)) {
3305 					if((temp_hostescalation->escalation_period = (char *)strdup(value)) == NULL)
3306 						result = ERROR;
3307 					}
3308 				temp_hostescalation->have_escalation_period = TRUE;
3309 				}
3310 			else if(!strcmp(variable, "first_notification")) {
3311 				temp_hostescalation->first_notification = atoi(value);
3312 				temp_hostescalation->have_first_notification = TRUE;
3313 				}
3314 			else if(!strcmp(variable, "last_notification")) {
3315 				temp_hostescalation->last_notification = atoi(value);
3316 				temp_hostescalation->have_last_notification = TRUE;
3317 				}
3318 			else if(!strcmp(variable, "notification_interval")) {
3319 				temp_hostescalation->notification_interval = strtod(value, NULL);
3320 				temp_hostescalation->have_notification_interval = TRUE;
3321 				}
3322 			else if(!strcmp(variable, "escalation_options")) {
3323 				for(temp_ptr = strtok(value, ", "); temp_ptr; temp_ptr = strtok(NULL, ", ")) {
3324 					if(!strcmp(temp_ptr, "d") || !strcmp(temp_ptr, "down"))
3325 						flag_set(temp_hostescalation->escalation_options, OPT_DOWN);
3326 					else if(!strcmp(temp_ptr, "u") || !strcmp(temp_ptr, "unreachable"))
3327 						flag_set(temp_hostescalation->escalation_options, OPT_UNREACHABLE);
3328 					else if(!strcmp(temp_ptr, "r") || !strcmp(temp_ptr, "recovery"))
3329 						flag_set(temp_hostescalation->escalation_options, OPT_RECOVERY);
3330 					else if(!strcmp(temp_ptr, "n") || !strcmp(temp_ptr, "none")) {
3331 						temp_hostescalation->escalation_options = OPT_NOTHING;
3332 						}
3333 					else if(!strcmp(temp_ptr, "a") || !strcmp(temp_ptr, "all")) {
3334 						temp_hostescalation->escalation_options = OPT_ALL;
3335 						}
3336 					else {
3337 						logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid escalation option '%s' in hostescalation definition.\n", temp_ptr);
3338 						return ERROR;
3339 						}
3340 					}
3341 				temp_hostescalation->have_escalation_options = TRUE;
3342 				}
3343 			else if(!strcmp(variable, "register"))
3344 				temp_hostescalation->register_object = (atoi(value) > 0) ? TRUE : FALSE;
3345 			else {
3346 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid hostescalation object directive '%s'.\n", variable);
3347 				return ERROR;
3348 				}
3349 
3350 			break;
3351 
3352 		case XODTEMPLATE_HOSTEXTINFO:
3353 
3354 			temp_hostextinfo = xodtemplate_hostextinfo_list;
3355 
3356 			if(!strcmp(variable, "use")) {
3357 				if((temp_hostextinfo->template = (char *)strdup(value)) == NULL)
3358 					result = ERROR;
3359 				}
3360 			else if(!strcmp(variable, "name")) {
3361 
3362 				if((temp_hostextinfo->name = (char *)strdup(value)) == NULL)
3363 					result = ERROR;
3364 
3365 				if(result == OK) {
3366 					/* add to template skiplist for fast searches */
3367 					result = skiplist_insert(xobject_template_skiplists[HOSTEXTINFO_SKIPLIST], (void *)temp_hostextinfo);
3368 					switch(result) {
3369 						case SKIPLIST_ERROR_DUPLICATE:
3370 							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);
3371 							result = ERROR;
3372 							break;
3373 						case SKIPLIST_OK:
3374 							result = OK;
3375 							break;
3376 						default:
3377 							result = ERROR;
3378 							break;
3379 						}
3380 					}
3381 				}
3382 			else if(!strcmp(variable, "host_name")) {
3383 				if(strcmp(value, XODTEMPLATE_NULL)) {
3384 					if((temp_hostextinfo->host_name = (char *)strdup(value)) == NULL)
3385 						result = ERROR;
3386 					}
3387 				temp_hostextinfo->have_host_name = TRUE;
3388 				}
3389 			else if(!strcmp(variable, "hostgroup") || !strcmp(variable, "hostgroup_name")) {
3390 				if(strcmp(value, XODTEMPLATE_NULL)) {
3391 					if((temp_hostextinfo->hostgroup_name = (char *)strdup(value)) == NULL)
3392 						result = ERROR;
3393 					}
3394 				temp_hostextinfo->have_hostgroup_name = TRUE;
3395 				}
3396 			else if(!strcmp(variable, "notes")) {
3397 				if(strcmp(value, XODTEMPLATE_NULL)) {
3398 					if((temp_hostextinfo->notes = (char *)strdup(value)) == NULL)
3399 						result = ERROR;
3400 					}
3401 				temp_hostextinfo->have_notes = TRUE;
3402 				}
3403 			else if(!strcmp(variable, "notes_url")) {
3404 				if(strcmp(value, XODTEMPLATE_NULL)) {
3405 					if((temp_hostextinfo->notes_url = (char *)strdup(value)) == NULL)
3406 						result = ERROR;
3407 					}
3408 				temp_hostextinfo->have_notes_url = TRUE;
3409 				}
3410 			else if(!strcmp(variable, "action_url")) {
3411 				if(strcmp(value, XODTEMPLATE_NULL)) {
3412 					if((temp_hostextinfo->action_url = (char *)strdup(value)) == NULL)
3413 						result = ERROR;
3414 					}
3415 				temp_hostextinfo->have_action_url = TRUE;
3416 				}
3417 			else if(!strcmp(variable, "icon_image")) {
3418 				if(strcmp(value, XODTEMPLATE_NULL)) {
3419 					if((temp_hostextinfo->icon_image = (char *)strdup(value)) == NULL)
3420 						result = ERROR;
3421 					}
3422 				temp_hostextinfo->have_icon_image = TRUE;
3423 				}
3424 			else if(!strcmp(variable, "icon_image_alt")) {
3425 				if(strcmp(value, XODTEMPLATE_NULL)) {
3426 					if((temp_hostextinfo->icon_image_alt = (char *)strdup(value)) == NULL)
3427 						result = ERROR;
3428 					}
3429 				temp_hostextinfo->have_icon_image_alt = TRUE;
3430 				}
3431 			else if(!strcmp(variable, "vrml_image")) {
3432 				if(strcmp(value, XODTEMPLATE_NULL)) {
3433 					if((temp_hostextinfo->vrml_image = (char *)strdup(value)) == NULL)
3434 						result = ERROR;
3435 					}
3436 				temp_hostextinfo->have_vrml_image = TRUE;
3437 				}
3438 			else if(!strcmp(variable, "gd2_image") || !strcmp(variable, "statusmap_image")) {
3439 				if(strcmp(value, XODTEMPLATE_NULL)) {
3440 					if((temp_hostextinfo->statusmap_image = (char *)strdup(value)) == NULL)
3441 						result = ERROR;
3442 					}
3443 				temp_hostextinfo->have_statusmap_image = TRUE;
3444 				}
3445 			else if(!strcmp(variable, "2d_coords")) {
3446 				temp_ptr = strtok(value, ", ");
3447 				if(temp_ptr == NULL) {
3448 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 2d_coords value '%s' in extended host info definition.\n", temp_ptr);
3449 					return ERROR;
3450 					}
3451 				temp_hostextinfo->x_2d = atoi(temp_ptr);
3452 				temp_ptr = strtok(NULL, ", ");
3453 				if(temp_ptr == NULL) {
3454 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 2d_coords value '%s' in extended host info definition.\n", temp_ptr);
3455 					return ERROR;
3456 					}
3457 				temp_hostextinfo->y_2d = atoi(temp_ptr);
3458 				temp_hostextinfo->have_2d_coords = TRUE;
3459 				}
3460 			else if(!strcmp(variable, "3d_coords")) {
3461 				temp_ptr = strtok(value, ", ");
3462 				if(temp_ptr == NULL) {
3463 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 3d_coords value '%s' in extended host info definition.\n", temp_ptr);
3464 					return ERROR;
3465 					}
3466 				temp_hostextinfo->x_3d = strtod(temp_ptr, NULL);
3467 				temp_ptr = strtok(NULL, ", ");
3468 				if(temp_ptr == NULL) {
3469 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 3d_coords value '%s' in extended host info definition.\n", temp_ptr);
3470 					return ERROR;
3471 					}
3472 				temp_hostextinfo->y_3d = strtod(temp_ptr, NULL);
3473 				temp_ptr = strtok(NULL, ", ");
3474 				if(temp_ptr == NULL) {
3475 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid 3d_coords value '%s' in extended host info definition.\n", temp_ptr);
3476 					return ERROR;
3477 					}
3478 				temp_hostextinfo->z_3d = strtod(temp_ptr, NULL);
3479 				temp_hostextinfo->have_3d_coords = TRUE;
3480 				}
3481 			else if(!strcmp(variable, "register"))
3482 				temp_hostextinfo->register_object = (atoi(value) > 0) ? TRUE : FALSE;
3483 			else {
3484 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid hostextinfo object directive '%s'.\n", variable);
3485 				return ERROR;
3486 				}
3487 
3488 			break;
3489 
3490 		case XODTEMPLATE_SERVICEEXTINFO:
3491 
3492 			temp_serviceextinfo = xodtemplate_serviceextinfo_list;
3493 
3494 			if(!strcmp(variable, "use")) {
3495 				if((temp_serviceextinfo->template = (char *)strdup(value)) == NULL)
3496 					result = ERROR;
3497 				}
3498 			else if(!strcmp(variable, "name")) {
3499 
3500 				if((temp_serviceextinfo->name = (char *)strdup(value)) == NULL)
3501 					result = ERROR;
3502 
3503 				if(result == OK) {
3504 					/* add to template skiplist for fast searches */
3505 					result = skiplist_insert(xobject_template_skiplists[SERVICEEXTINFO_SKIPLIST], (void *)temp_serviceextinfo);
3506 					switch(result) {
3507 						case SKIPLIST_ERROR_DUPLICATE:
3508 							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);
3509 							result = ERROR;
3510 							break;
3511 						case SKIPLIST_OK:
3512 							result = OK;
3513 							break;
3514 						default:
3515 							result = ERROR;
3516 							break;
3517 						}
3518 					}
3519 				}
3520 			else if(!strcmp(variable, "host_name")) {
3521 				if(strcmp(value, XODTEMPLATE_NULL)) {
3522 					if((temp_serviceextinfo->host_name = (char *)strdup(value)) == NULL)
3523 						result = ERROR;
3524 					}
3525 				temp_serviceextinfo->have_host_name = TRUE;
3526 				}
3527 			else if(!strcmp(variable, "hostgroup") || !strcmp(variable, "hostgroup_name")) {
3528 				if(strcmp(value, XODTEMPLATE_NULL)) {
3529 					if((temp_serviceextinfo->hostgroup_name = (char *)strdup(value)) == NULL)
3530 						result = ERROR;
3531 					}
3532 				temp_serviceextinfo->have_hostgroup_name = TRUE;
3533 				}
3534 			else if(!strcmp(variable, "service_description")) {
3535 				if(strcmp(value, XODTEMPLATE_NULL)) {
3536 					if((temp_serviceextinfo->service_description = (char *)strdup(value)) == NULL)
3537 						result = ERROR;
3538 					}
3539 				temp_serviceextinfo->have_service_description = TRUE;
3540 				}
3541 			else if(!strcmp(variable, "notes")) {
3542 				if(strcmp(value, XODTEMPLATE_NULL)) {
3543 					if((temp_serviceextinfo->notes = (char *)strdup(value)) == NULL)
3544 						result = ERROR;
3545 					}
3546 				temp_serviceextinfo->have_notes = TRUE;
3547 				}
3548 			else if(!strcmp(variable, "notes_url")) {
3549 				if(strcmp(value, XODTEMPLATE_NULL)) {
3550 					if((temp_serviceextinfo->notes_url = (char *)strdup(value)) == NULL)
3551 						result = ERROR;
3552 					}
3553 				temp_serviceextinfo->have_notes_url = TRUE;
3554 				}
3555 			else if(!strcmp(variable, "action_url")) {
3556 				if(strcmp(value, XODTEMPLATE_NULL)) {
3557 					if((temp_serviceextinfo->action_url = (char *)strdup(value)) == NULL)
3558 						result = ERROR;
3559 					}
3560 				temp_serviceextinfo->have_action_url = TRUE;
3561 				}
3562 			else if(!strcmp(variable, "icon_image")) {
3563 				if(strcmp(value, XODTEMPLATE_NULL)) {
3564 					if((temp_serviceextinfo->icon_image = (char *)strdup(value)) == NULL)
3565 						result = ERROR;
3566 					}
3567 				temp_serviceextinfo->have_icon_image = TRUE;
3568 				}
3569 			else if(!strcmp(variable, "icon_image_alt")) {
3570 				if(strcmp(value, XODTEMPLATE_NULL)) {
3571 					if((temp_serviceextinfo->icon_image_alt = (char *)strdup(value)) == NULL)
3572 						result = ERROR;
3573 					}
3574 				temp_serviceextinfo->have_icon_image_alt = TRUE;
3575 				}
3576 			else if(!strcmp(variable, "register"))
3577 				temp_serviceextinfo->register_object = (atoi(value) > 0) ? TRUE : FALSE;
3578 			else {
3579 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid serviceextinfo object directive '%s'.\n", variable);
3580 				return ERROR;
3581 				}
3582 
3583 			break;
3584 
3585 		default:
3586 			return ERROR;
3587 			break;
3588 		}
3589 
3590 	return result;
3591 	}
3592 
3593 
3594 
3595 #define xod_check_complete(otype) \
3596 	do { \
3597 		xodtemplate_##otype *o = (xodtemplate_##otype *)xodtemplate_current_object; \
3598 		if (o->register_object && !o->otype##_name && !o->name) { \
3599 			return ERROR; \
3600 		} \
3601 	} while(0)
3602 /* completes an object definition */
xodtemplate_end_object_definition(int options)3603 int xodtemplate_end_object_definition(int options) {
3604 	int result = OK;
3605 
3606 	switch(xodtemplate_current_object_type) {
3607 	case XODTEMPLATE_HOSTESCALATION:
3608 		xodcount.hostescalations += !!use_precached_objects;
3609 		break;
3610 	case XODTEMPLATE_SERVICEESCALATION:
3611 		xodcount.serviceescalations += !!use_precached_objects;
3612 		break;
3613 	case XODTEMPLATE_TIMEPERIOD:
3614 		xod_check_complete(timeperiod);
3615 		break;
3616 	case XODTEMPLATE_COMMAND:
3617 		xod_check_complete(command);
3618 		break;
3619 	case XODTEMPLATE_CONTACT:
3620 		xod_check_complete(contact);
3621 		break;
3622 	case XODTEMPLATE_CONTACTGROUP:
3623 		xod_check_complete(contactgroup);
3624 		break;
3625 	case XODTEMPLATE_HOST:
3626 		xod_check_complete(host);
3627 		break;
3628 	case XODTEMPLATE_HOSTGROUP:
3629 		xod_check_complete(hostgroup);
3630 		break;
3631 	case XODTEMPLATE_SERVICEGROUP:
3632 		xod_check_complete(servicegroup);
3633 		break;
3634 	}
3635 
3636 
3637 	xodtemplate_current_object = NULL;
3638 	xodtemplate_current_object_type = XODTEMPLATE_NONE;
3639 
3640 	return result;
3641 	}
3642 
3643 
3644 
3645 /* adds a custom variable to a host */
xodtemplate_add_custom_variable_to_host(xodtemplate_host * hst,char * varname,char * varvalue)3646 xodtemplate_customvariablesmember *xodtemplate_add_custom_variable_to_host(xodtemplate_host *hst, char *varname, char *varvalue) {
3647 
3648 	return xodtemplate_add_custom_variable_to_object(&hst->custom_variables, varname, varvalue);
3649 	}
3650 
3651 
3652 
3653 /* adds a custom variable to a service */
xodtemplate_add_custom_variable_to_service(xodtemplate_service * svc,char * varname,char * varvalue)3654 xodtemplate_customvariablesmember *xodtemplate_add_custom_variable_to_service(xodtemplate_service *svc, char *varname, char *varvalue) {
3655 
3656 	return xodtemplate_add_custom_variable_to_object(&svc->custom_variables, varname, varvalue);
3657 	}
3658 
3659 
3660 
3661 /* adds a custom variable to a contact */
xodtemplate_add_custom_variable_to_contact(xodtemplate_contact * cntct,char * varname,char * varvalue)3662 xodtemplate_customvariablesmember *xodtemplate_add_custom_variable_to_contact(xodtemplate_contact *cntct, char *varname, char *varvalue) {
3663 
3664 	return xodtemplate_add_custom_variable_to_object(&cntct->custom_variables, varname, varvalue);
3665 	}
3666 
3667 
3668 
3669 /* adds a custom variable to an object */
xodtemplate_add_custom_variable_to_object(xodtemplate_customvariablesmember ** object_ptr,char * varname,char * varvalue)3670 xodtemplate_customvariablesmember *xodtemplate_add_custom_variable_to_object(xodtemplate_customvariablesmember **object_ptr, char *varname, char *varvalue) {
3671 	xodtemplate_customvariablesmember *new_customvariablesmember = NULL;
3672 	register int x = 0;
3673 
3674 	/* make sure we have the data we need */
3675 	if(object_ptr == NULL)
3676 		return NULL;
3677 
3678 	if(varname == NULL || !strcmp(varname, ""))
3679 		return NULL;
3680 
3681 	/* allocate memory for a new member */
3682 	if((new_customvariablesmember = malloc(sizeof(xodtemplate_customvariablesmember))) == NULL)
3683 		return NULL;
3684 	if((new_customvariablesmember->variable_name = (char *)strdup(varname)) == NULL) {
3685 		my_free(new_customvariablesmember);
3686 		return NULL;
3687 		}
3688 	if(varvalue && *varvalue) {
3689 		if((new_customvariablesmember->variable_value = (char *)strdup(varvalue)) == NULL) {
3690 			my_free(new_customvariablesmember->variable_name);
3691 			my_free(new_customvariablesmember);
3692 			return NULL;
3693 			}
3694 		}
3695 	else
3696 		new_customvariablesmember->variable_value = NULL;
3697 
3698 	/* convert varname to all uppercase (saves CPU time during macro functions) */
3699 	for(x = 0; new_customvariablesmember->variable_name[x] != '\x0'; x++)
3700 		new_customvariablesmember->variable_name[x] = toupper(new_customvariablesmember->variable_name[x]);
3701 
3702 	/* add the new member to the head of the member list */
3703 	new_customvariablesmember->next = *object_ptr;
3704 	*object_ptr = new_customvariablesmember;
3705 
3706 	return new_customvariablesmember;
3707 	}
3708 
3709 
3710 
3711 /* parses a timeperiod directive... :-) */
xodtemplate_parse_timeperiod_directive(xodtemplate_timeperiod * tperiod,char * var,char * val)3712 int xodtemplate_parse_timeperiod_directive(xodtemplate_timeperiod *tperiod, char *var, char *val) {
3713 	char *input = NULL;
3714 	char temp_buffer[5][MAX_INPUT_BUFFER] = {"", "", "", "", ""};
3715 	int items = 0;
3716 	int result = OK;
3717 
3718 	int syear = 0;
3719 	int smon = 0;
3720 	int smday = 0;
3721 	int swday = 0;
3722 	int swday_offset = 0;
3723 	int eyear = 0;
3724 	int emon = 0;
3725 	int emday = 0;
3726 	int ewday = 0;
3727 	int ewday_offset = 0;
3728 	int skip_interval = 0;
3729 
3730 	/* make sure we've got the reqs */
3731 	if(tperiod == NULL || var == NULL || val == NULL)
3732 		return ERROR;
3733 
3734 	/* we'll need the full (unsplit) input later */
3735 	if((input = (char *)malloc(strlen(var) + strlen(val) + 2)) == NULL)
3736 		return ERROR;
3737 	strcpy(input, var);
3738 	strcat(input, " ");
3739 	strcat(input, val);
3740 
3741 	if(0)
3742 		return OK;
3743 
3744 	/* calendar dates */
3745 	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) {
3746 		/* add timerange exception */
3747 		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)
3748 			result = ERROR;
3749 		}
3750 
3751 	else if((items = sscanf(input, "%4d-%2d-%2d / %d %[0-9:, -]", &syear, &smon, &smday, &skip_interval, temp_buffer[0])) == 5) {
3752 		eyear = syear;
3753 		emon = smon;
3754 		emday = smday;
3755 		/* add timerange exception */
3756 		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)
3757 			result = ERROR;
3758 		}
3759 
3760 	else if((items = sscanf(input, "%4d-%2d-%2d - %4d-%2d-%2d %[0-9:, -]", &syear, &smon, &smday, &eyear, &emon, &emday, temp_buffer[0])) == 7) {
3761 		/* add timerange exception */
3762 		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)
3763 			result = ERROR;
3764 		}
3765 
3766 	else if((items = sscanf(input, "%4d-%2d-%2d %[0-9:, -]", &syear, &smon, &smday, temp_buffer[0])) == 4) {
3767 		eyear = syear;
3768 		emon = smon;
3769 		emday = smday;
3770 		/* add timerange exception */
3771 		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)
3772 			result = ERROR;
3773 		}
3774 
3775 	/* other types... */
3776 	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) {
3777 		/* wednesday 1 january - thursday 2 july / 3 */
3778 		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) {
3779 			/* add timeperiod exception */
3780 			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)
3781 				result = ERROR;
3782 			}
3783 		}
3784 
3785 	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) {
3786 		/* february 1 - march 15 / 3 */
3787 		/* monday 2 - thursday 3 / 2 */
3788 		/* day 4 - day 6 / 2 */
3789 		if((result = xodtemplate_get_weekday_from_string(temp_buffer[0], &swday)) == OK && (result = xodtemplate_get_weekday_from_string(temp_buffer[1], &ewday)) == OK) {
3790 			/* monday 2 - thursday 3 / 2 */
3791 			swday_offset = smday;
3792 			ewday_offset = emday;
3793 			/* add timeperiod exception */
3794 			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)
3795 				result = ERROR;
3796 			}
3797 		else if((result = xodtemplate_get_month_from_string(temp_buffer[0], &smon)) == OK && (result = xodtemplate_get_month_from_string(temp_buffer[1], &emon)) == OK) {
3798 			/* february 1 - march 15 / 3 */
3799 			/* add timeperiod exception */
3800 			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)
3801 				result = ERROR;
3802 			}
3803 		else if(!strcmp(temp_buffer[0], "day")  && !strcmp(temp_buffer[1], "day")) {
3804 			/* day 4 - 6 / 2 */
3805 			/* add timeperiod exception */
3806 			result = OK;
3807 			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)
3808 				result = ERROR;
3809 			}
3810 		}
3811 
3812 	else if((items = sscanf(input, "%[a-z] %d - %d / %d %[0-9:, -]", temp_buffer[0], &smday, &emday, &skip_interval, temp_buffer[1])) == 5) {
3813 		/* february 1 - 15 / 3 */
3814 		/* monday 2 - 3 / 2 */
3815 		/* day 1 - 25 / 4 */
3816 		if((result = xodtemplate_get_weekday_from_string(temp_buffer[0], &swday)) == OK) {
3817 			/* thursday 2 - 4 */
3818 			swday_offset = smday;
3819 			ewday = swday;
3820 			ewday_offset = emday;
3821 			/* add timeperiod exception */
3822 			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)
3823 				result = ERROR;
3824 			}
3825 		else if((result = xodtemplate_get_month_from_string(temp_buffer[0], &smon)) == OK) {
3826 			/* february 3 - 5 */
3827 			emon = smon;
3828 			/* add timeperiod exception */
3829 			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)
3830 				result = ERROR;
3831 			}
3832 		else if(!strcmp(temp_buffer[0], "day")) {
3833 			/* day 1 - 4 */
3834 			/* add timeperiod exception */
3835 			result = OK;
3836 			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)
3837 				result = ERROR;
3838 			}
3839 		}
3840 
3841 	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) {
3842 		/* wednesday 1 january - thursday 2 july */
3843 		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) {
3844 			/* add timeperiod exception */
3845 			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)
3846 				result = ERROR;
3847 			}
3848 		}
3849 
3850 	else if((items = sscanf(input, "%[a-z] %d - %d %[0-9:, -]", temp_buffer[0], &smday, &emday, temp_buffer[1])) == 4) {
3851 		/* february 3 - 5 */
3852 		/* thursday 2 - 4 */
3853 		/* day 1 - 4 */
3854 		if((result = xodtemplate_get_weekday_from_string(temp_buffer[0], &swday)) == OK) {
3855 			/* thursday 2 - 4 */
3856 			swday_offset = smday;
3857 			ewday = swday;
3858 			ewday_offset = emday;
3859 			/* add timeperiod exception */
3860 			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)
3861 				result = ERROR;
3862 			}
3863 		else if((result = xodtemplate_get_month_from_string(temp_buffer[0], &smon)) == OK) {
3864 			/* february 3 - 5 */
3865 			emon = smon;
3866 			/* add timeperiod exception */
3867 			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)
3868 				result = ERROR;
3869 			}
3870 		else if(!strcmp(temp_buffer[0], "day")) {
3871 			/* day 1 - 4 */
3872 			/* add timeperiod exception */
3873 			result = OK;
3874 			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)
3875 				result = ERROR;
3876 			}
3877 		}
3878 
3879 	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) {
3880 		/* february 1 - march 15 */
3881 		/* monday 2 - thursday 3 */
3882 		/* day 1 - day 5 */
3883 		if((result = xodtemplate_get_weekday_from_string(temp_buffer[0], &swday)) == OK && (result = xodtemplate_get_weekday_from_string(temp_buffer[1], &ewday)) == OK) {
3884 			/* monday 2 - thursday 3 */
3885 			swday_offset = smday;
3886 			ewday_offset = emday;
3887 			/* add timeperiod exception */
3888 			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)
3889 				result = ERROR;
3890 			}
3891 		else if((result = xodtemplate_get_month_from_string(temp_buffer[0], &smon)) == OK && (result = xodtemplate_get_month_from_string(temp_buffer[1], &emon)) == OK) {
3892 			/* february 1 - march 15 */
3893 			/* add timeperiod exception */
3894 			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)
3895 				result = ERROR;
3896 			}
3897 		else if(!strcmp(temp_buffer[0], "day")  && !strcmp(temp_buffer[1], "day")) {
3898 			/* day 1 - day 5 */
3899 			/* add timeperiod exception */
3900 			result = OK;
3901 			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)
3902 				result = ERROR;
3903 			}
3904 		}
3905 
3906 	else if((items = sscanf(input, "%[a-z] %d%*[ \t]%[0-9:, -]", temp_buffer[0], &smday, temp_buffer[1])) == 3) {
3907 		/* february 3 */
3908 		/* thursday 2 */
3909 		/* day 1 */
3910 		if((result = xodtemplate_get_weekday_from_string(temp_buffer[0], &swday)) == OK) {
3911 			/* thursday 2 */
3912 			swday_offset = smday;
3913 			ewday = swday;
3914 			ewday_offset = swday_offset;
3915 			/* add timeperiod exception */
3916 			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)
3917 				result = ERROR;
3918 			}
3919 		else if((result = xodtemplate_get_month_from_string(temp_buffer[0], &smon)) == OK) {
3920 			/* february 3 */
3921 			emon = smon;
3922 			emday = smday;
3923 			/* add timeperiod exception */
3924 			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)
3925 				result = ERROR;
3926 			}
3927 		else if(!strcmp(temp_buffer[0], "day")) {
3928 			/* day 1 */
3929 			emday = smday;
3930 			/* add timeperiod exception */
3931 			result = OK;
3932 			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)
3933 				result = ERROR;
3934 			}
3935 		}
3936 
3937 	else if((items = sscanf(input, "%[a-z] %d %[a-z] %[0-9:, -]", temp_buffer[0], &swday_offset, temp_buffer[1], temp_buffer[2])) == 4) {
3938 		/* thursday 3 february */
3939 		if((result = xodtemplate_get_weekday_from_string(temp_buffer[0], &swday)) == OK && (result = xodtemplate_get_month_from_string(temp_buffer[1], &smon)) == OK) {
3940 			emon = smon;
3941 			ewday = swday;
3942 			ewday_offset = swday_offset;
3943 			/* add timeperiod exception */
3944 			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)
3945 				result = ERROR;
3946 			}
3947 		}
3948 
3949 	else if((items = sscanf(input, "%[a-z] %[0-9:, -]", temp_buffer[0], temp_buffer[1])) == 2) {
3950 		/* monday */
3951 		if((result = xodtemplate_get_weekday_from_string(temp_buffer[0], &swday)) == OK) {
3952 			/* add normal weekday timerange */
3953 			if((tperiod->timeranges[swday] = (char *)strdup(temp_buffer[1])) == NULL)
3954 				result = ERROR;
3955 			}
3956 		}
3957 
3958 	else
3959 		result = ERROR;
3960 
3961 #ifdef NSCORE
3962 	if(result == ERROR) {
3963 		printf("Error: Could not parse timeperiod directive '%s'!\n", input);
3964 		}
3965 #endif
3966 
3967 	/* free memory */
3968 	my_free(input);
3969 
3970 	return result;
3971 	}
3972 
3973 
3974 
3975 /* 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)3976 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) {
3977 	xodtemplate_daterange *new_daterange = NULL;
3978 
3979 	/* make sure we have the data we need */
3980 	if(period == NULL || timeranges == NULL)
3981 		return NULL;
3982 
3983 	/* allocate memory for the date range range */
3984 	if((new_daterange = malloc(sizeof(xodtemplate_daterange))) == NULL)
3985 		return NULL;
3986 
3987 	new_daterange->next = NULL;
3988 
3989 	new_daterange->type = type;
3990 	new_daterange->syear = syear;
3991 	new_daterange->smon = smon;
3992 	new_daterange->smday = smday;
3993 	new_daterange->swday = swday;
3994 	new_daterange->swday_offset = swday_offset;
3995 	new_daterange->eyear = eyear;
3996 	new_daterange->emon = emon;
3997 	new_daterange->emday = emday;
3998 	new_daterange->ewday = ewday;
3999 	new_daterange->ewday_offset = ewday_offset;
4000 	new_daterange->skip_interval = skip_interval;
4001 	new_daterange->timeranges = (char *)strdup(timeranges);
4002 
4003 	/* add the new date range to the head of the range list for this exception type */
4004 	new_daterange->next = period->exceptions[type];
4005 	period->exceptions[type] = new_daterange;
4006 
4007 	return new_daterange;
4008 	}
4009 
4010 
4011 
xodtemplate_get_month_from_string(char * str,int * month)4012 int xodtemplate_get_month_from_string(char *str, int *month) {
4013 	const char *months[12] = {"january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"};
4014 	int x = 0;
4015 
4016 	if(str == NULL || month == NULL)
4017 		return ERROR;
4018 
4019 	for(x = 0; x < 12; x++) {
4020 		if(!strcmp(str, months[x])) {
4021 			*month = x;
4022 			return OK;
4023 			}
4024 		}
4025 
4026 	return ERROR;
4027 	}
4028 
4029 
4030 
4031 
xodtemplate_get_weekday_from_string(char * str,int * weekday)4032 int xodtemplate_get_weekday_from_string(char *str, int *weekday) {
4033 	const char *days[7] = {"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"};
4034 	int x = 0;
4035 
4036 	if(str == NULL || weekday == NULL)
4037 		return ERROR;
4038 
4039 	for(x = 0; x < 7; x++) {
4040 		if(!strcmp(str, days[x])) {
4041 			*weekday = x;
4042 			return OK;
4043 			}
4044 		}
4045 
4046 	return ERROR;
4047 	}
4048 
4049 
4050 
4051 /******************************************************************/
4052 /***************** OBJECT DUPLICATION FUNCTIONS *******************/
4053 /******************************************************************/
4054 
4055 #ifdef NSCORE
4056 
4057 /* duplicates service definitions */
xodtemplate_duplicate_services(void)4058 int xodtemplate_duplicate_services(void) {
4059 	int result = OK;
4060 	xodtemplate_service *temp_service = NULL;
4061 
4062 	xodcount.services = 0;
4063 	/****** DUPLICATE SERVICE DEFINITIONS WITH ONE OR MORE HOSTGROUP AND/OR HOST NAMES ******/
4064 	for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) {
4065 		objectlist *hlist = NULL, *list = NULL, *glist = NULL, *next;
4066 		xodtemplate_hostgroup fake_hg;
4067 
4068 		/* clear for each round */
4069 		bitmap_clear(host_map);
4070 
4071 		/* skip services that shouldn't be registered */
4072 		if(temp_service->register_object == FALSE)
4073 			continue;
4074 
4075 		/* bail out on service definitions without enough data */
4076 		if((temp_service->hostgroup_name == NULL && temp_service->host_name == NULL) || temp_service->service_description == NULL) {
4077 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Service has no hosts and/or service_description (config file '%s', starting on line %d)\n", xodtemplate_config_file_name(temp_service->_config_file), temp_service->_start_line);
4078 			return ERROR;
4079 			}
4080 
4081 		if(temp_service->hostgroup_name != NULL) {
4082 			if(xodtemplate_expand_hostgroups(&glist, host_map, temp_service->hostgroup_name, temp_service->_config_file, temp_service->_start_line) == ERROR) {
4083 				return ERROR;
4084 				}
4085 			/* no longer needed */
4086 			my_free(temp_service->hostgroup_name);
4087 
4088 			/* empty result is only bad if allow_empty_hostgroup_assignment is off */
4089 			if(!glist && !bitmap_count_set_bits(host_map)) {
4090 				if(!allow_empty_hostgroup_assignment) {
4091 					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);
4092 					return ERROR;
4093 					}
4094 				else if (allow_empty_hostgroup_assignment == 2) {
4095 					logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: 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);
4096 					}
4097 				}
4098 			}
4099 
4100 		/* now find direct hosts */
4101 		if(temp_service->host_name) {
4102 			if (xodtemplate_expand_hosts(&hlist, host_map, temp_service->host_name, temp_service->_config_file, temp_service->_start_line) != OK) {
4103 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Failed to expand host list '%s' for service '%s' (%s:%d)\n",
4104 					  temp_service->host_name, temp_service->service_description,
4105 					  xodtemplate_config_file_name(temp_service->_config_file),
4106 					  temp_service->_start_line);
4107 				return ERROR;
4108 				}
4109 			/* we don't need this anymore now that we have the hlist */
4110 			my_free(temp_service->host_name);
4111 		}
4112 
4113 		/*
4114 		 * host_map now contains all rejected hosts
4115 		 * group_map contains all rejected hostgroups
4116 		 * hlist contains all hosts we're directly assigned to.
4117 		 * glist contains all hostgroups we're assigned to.
4118 		 * We ignore hostgroups we're assigned to that are also rejected.
4119 		 * We do a dirty trick here and prepend a fake hostgroup
4120 		 * to the hostgroup list so we can use the same loop for
4121 		 * the rest of the code.
4122 		 */
4123 		fake_hg.hostgroup_name = "!!FAKE HOSTGROUP";
4124 		fake_hg.member_list = hlist;
4125 		prepend_object_to_objectlist(&glist, &fake_hg);
4126 		for(list = glist; list; list = next) {
4127 			xodtemplate_hostgroup *hg = (xodtemplate_hostgroup *)list->object_ptr;
4128 			next = list->next;
4129 			free(list);
4130 
4131 			/* we don't free this list */
4132 			for(hlist = hg->member_list; hlist; hlist = hlist->next) {
4133 				xodtemplate_host *h = (xodtemplate_host *)hlist->object_ptr;
4134 
4135 				/* ignore this host if it's rejected */
4136 				if(bitmap_isset(host_map, h->id))
4137 					continue;
4138 
4139 				/*
4140 				 * reject more copies of this host. This happens
4141 				 * if the service is assigned to multiple hostgroups
4142 				 * where the same host is part of more than one of
4143 				 * them
4144 				 */
4145 				bitmap_set(host_map, h->id);
4146 
4147 				/* if this is the last duplication, use the existing entry */
4148 				if(!next && !hlist->next) {
4149 					temp_service->id = xodcount.services++;
4150 					temp_service->host_name = h->host_name;
4151 					}
4152 				else {
4153 					/* duplicate service definition */
4154 					result = xodtemplate_duplicate_service(temp_service, h->host_name, hg != &fake_hg);
4155 					}
4156 				}
4157 			free_objectlist(&fake_hg.member_list);
4158 			}
4159 		}
4160 
4161 	/***************************************/
4162 	/* SKIPLIST STUFF FOR FAST SORT/SEARCH */
4163 	/***************************************/
4164 
4165 	/* First loop for single host service definition*/
4166 	for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) {
4167 		/* skip services that shouldn't be registered */
4168 		if(temp_service->register_object == FALSE)
4169 			continue;
4170 
4171 		/* skip service definitions without enough data */
4172 		if(temp_service->host_name == NULL || temp_service->service_description == NULL)
4173 			continue;
4174 
4175 		if(temp_service->is_from_hostgroup) {
4176 			continue;
4177 			}
4178 
4179 
4180 		result = skiplist_insert(xobject_skiplists[SERVICE_SKIPLIST], (void *)temp_service);
4181 		switch(result) {
4182 			case SKIPLIST_ERROR_DUPLICATE:
4183 				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);
4184 				result = ERROR;
4185 				break;
4186 			case SKIPLIST_OK:
4187 				result = OK;
4188 				break;
4189 			default:
4190 				result = ERROR;
4191 				break;
4192 			}
4193 		}
4194 
4195 
4196 	/* second loop for host group service definition*/
4197 	/* add services to skiplist for fast searches */
4198 	for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) {
4199 
4200 		/* skip services that shouldn't be registered */
4201 		if(temp_service->register_object == FALSE)
4202 			continue;
4203 
4204 		/* skip service definitions without enough data */
4205 		if(temp_service->host_name == NULL || temp_service->service_description == NULL)
4206 			continue;
4207 
4208 		if(!temp_service->is_from_hostgroup) {
4209 			continue;
4210 			}
4211 
4212 		temp_service->is_from_hostgroup = 0;
4213 
4214 		result = skiplist_insert(xobject_skiplists[SERVICE_SKIPLIST], (void *)temp_service);
4215 		switch(result) {
4216 			case SKIPLIST_ERROR_DUPLICATE:
4217 				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);
4218 				result = ERROR;
4219 				break;
4220 			case SKIPLIST_OK:
4221 				result = OK;
4222 				break;
4223 			default:
4224 				result = ERROR;
4225 				break;
4226 			}
4227 		}
4228 
4229 	return OK;
4230 	}
4231 
4232 
4233 /**
4234  * Create an objectlist of services from whatever someone put into a
4235  * servicedescription. Rules go like this:
4236  * NOT servicegroup:
4237  * If we have host_name and service_description, we do a simple
4238  * lookup.
4239  * If we have host_name and/or hostgroup_name and service_description,
4240  * we do multiple lookups and concatenate the results.
4241  * If we have host_name/hostgroup_name and service_description, we do multiple
4242  * simple lookups and concatenate the results.
4243  */
xodtemplate_create_service_list(objectlist ** ret,bitmap * reject_map,char * host_name,char * hostgroup_name,char * servicegroup_name,char * service_description,int _config_file,int _start_line)4244 static int xodtemplate_create_service_list(objectlist **ret, bitmap *reject_map, char *host_name, char *hostgroup_name, char *servicegroup_name, char *service_description, int _config_file, int _start_line)
4245 {
4246 	objectlist *hlist = NULL, *hglist = NULL, *slist = NULL, *sglist = NULL;
4247 	objectlist *glist, *gnext, *list, *next; /* iterators */
4248 	xodtemplate_hostgroup fake_hg;
4249 	bitmap *in;
4250 
4251 	/*
4252 	 * if we have a service_description, we need host_name
4253 	 * or host_group name
4254 	 */
4255 	if(service_description && !host_name && !hostgroup_name)
4256 		return ERROR;
4257 	/*
4258 	 * if we have host_name or a hostgroup_name we also need
4259 	 * service_description
4260 	 */
4261 	if((host_name || hostgroup_name) && !service_description)
4262 		return ERROR;
4263 
4264 	/* we'll need these */
4265 	bitmap_clear(host_map);
4266 	if (!(in = bitmap_create(xodcount.services)))
4267 		return ERROR;
4268 
4269 	/*
4270 	 * all services in the accepted servicegroups can be added, except
4271 	 * if they're also in service_map, in which case they're also
4272 	 * in rejected servicegroups and must NOT be added
4273 	 */
4274 	if(servicegroup_name && xodtemplate_expand_servicegroups(&sglist, reject_map, servicegroup_name, _config_file, _start_line) != OK)
4275 		return ERROR;
4276 	for(glist = sglist; glist; glist = gnext) {
4277 		xodtemplate_servicegroup *sg = (xodtemplate_servicegroup *)glist->object_ptr;
4278 		gnext = glist->next;
4279 		free(glist); /* free it as we go along */
4280 		for(list = sg->member_list; list; list = list->next) {
4281 			xodtemplate_service *s = (xodtemplate_service *)list->object_ptr;
4282 
4283 			/* rejected or already added */
4284 			if(bitmap_isset(in, s->id) || bitmap_isset(reject_map, s->id))
4285 				continue;
4286 			bitmap_set(in, s->id);
4287 			if(prepend_object_to_objectlist(ret, s) != OK) {
4288 				free_objectlist(&gnext);
4289 				return ERROR;
4290 			}
4291 		}
4292 	}
4293 
4294 	/*
4295 	 * get the lists we'll need, with reject markers included.
4296 	 * We have to get both hostlist and hostgroup list at once
4297 	 * to get the full reject markers.
4298 	 */
4299 	if(host_name && xodtemplate_expand_hosts(&hlist, host_map, host_name, _config_file, _start_line) != OK)
4300 		return ERROR;
4301 	if(hostgroup_name && xodtemplate_expand_hostgroups(&hglist, host_map, hostgroup_name, _config_file, _start_line) != OK) {
4302 		free_objectlist(&hlist);
4303 		return ERROR;
4304 	}
4305 
4306 	/*
4307 	 * if hlist isn't NULL, we add a fake hostgroup to the mix so we
4308 	 * can get away with a single loop, but we must always set its
4309 	 * memberlist so we can safely call free_objectlist() on it.
4310 	 */
4311 	fake_hg.member_list = hlist;
4312 	if(hlist) {
4313 		if(prepend_object_to_objectlist(&hglist, &fake_hg) != OK) {
4314 			free_objectlist(&hlist);
4315 			free_objectlist(&hglist);
4316 			bitmap_destroy(in);
4317 			return ERROR;
4318 		}
4319 	}
4320 
4321 	for(glist = hglist; glist; glist = gnext) {
4322 		xodtemplate_hostgroup *hg = (xodtemplate_hostgroup *)glist->object_ptr;
4323 		gnext = glist->next;
4324 		free(glist);
4325 
4326 		for(hlist = hg->member_list; hlist; hlist = hlist->next) {
4327 			xodtemplate_host *h = (xodtemplate_host *)hlist->object_ptr;
4328 			if(bitmap_isset(host_map, h->id))
4329 				continue;
4330 
4331 			/* expand services and add them all, unless they're rejected */
4332 			slist = NULL;
4333 			if(xodtemplate_expand_services(&slist, reject_map, h->host_name, service_description, _config_file, _start_line) != OK) {
4334 				free_objectlist(&gnext);
4335 				bitmap_destroy(in);
4336 				return ERROR;
4337 			}
4338 			for(list = slist; list; list = next) {
4339 				xodtemplate_service *s = (xodtemplate_service *)list->object_ptr;
4340 				next = list->next;
4341 				free(list);
4342 				if(bitmap_isset(in, s->id) || bitmap_isset(reject_map, s->id))
4343 					continue;
4344 				bitmap_set(in, s->id);
4345 				if(prepend_object_to_objectlist(ret, s) != OK) {
4346 					free_objectlist(&next);
4347 					free_objectlist(&gnext);
4348 					free_objectlist(&fake_hg.member_list);
4349 					bitmap_destroy(in);
4350 					return ERROR;
4351 				}
4352 			}
4353 		}
4354 	}
4355 
4356 	bitmap_destroy(in);
4357 	free_objectlist(&fake_hg.member_list);
4358 	return OK;
4359 }
4360 
4361 /* duplicates object definitions */
xodtemplate_duplicate_objects(void)4362 int xodtemplate_duplicate_objects(void) {
4363 	int result = OK;
4364 	xodtemplate_hostescalation *temp_hostescalation = NULL;
4365 	xodtemplate_serviceescalation *temp_serviceescalation = NULL;
4366 	xodtemplate_hostextinfo *next_he = NULL, *temp_hostextinfo = NULL;
4367 	xodtemplate_serviceextinfo *next_se = NULL, *temp_serviceextinfo = NULL;
4368 	objectlist *master_hostlist, *master_servicelist;
4369 	objectlist *list, *next;
4370 
4371 
4372 	/*************************************/
4373 	/* SERVICES ARE DUPLICATED ELSEWHERE */
4374 	/*************************************/
4375 
4376 
4377 	/* duplicate host escalations */
4378 	for(temp_hostescalation = xodtemplate_hostescalation_list; temp_hostescalation != NULL; temp_hostescalation = temp_hostescalation->next) {
4379 
4380 		/* skip host escalation definitions without enough data */
4381 		if(temp_hostescalation->hostgroup_name == NULL && temp_hostescalation->host_name == NULL)
4382 			continue;
4383 
4384 		/* get list of hosts */
4385 		master_hostlist = xodtemplate_expand_hostgroups_and_hosts(temp_hostescalation->hostgroup_name, temp_hostescalation->host_name, temp_hostescalation->_config_file, temp_hostescalation->_start_line);
4386 		if(master_hostlist == NULL) {
4387 			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);
4388 			return ERROR;
4389 			}
4390 
4391 		/* add a copy of the hostescalation for every host in the hostgroup/host name list */
4392 		for(list = master_hostlist; list; list = next) {
4393 			xodtemplate_host *h = (xodtemplate_host *)list->object_ptr;
4394 			next = list->next;
4395 			free(list);
4396 
4397 			xodcount.hostescalations++;
4398 
4399 			/* if this is the last duplication, use the existing entry */
4400 			if(!next) {
4401 				my_free(temp_hostescalation->name);
4402 				my_free(temp_hostescalation->template);
4403 				my_free(temp_hostescalation->host_name);
4404 				my_free(temp_hostescalation->hostgroup_name);
4405 				temp_hostescalation->host_name = h->host_name;
4406 				continue;
4407 				}
4408 
4409 			/* duplicate hostescalation definition */
4410 			result = xodtemplate_duplicate_hostescalation(temp_hostescalation, h->host_name);
4411 
4412 			/* exit on error */
4413 			if(result == ERROR) {
4414 				free_objectlist(&next);
4415 				return ERROR;
4416 				}
4417 			}
4418 		}
4419 	timing_point("Created %u hostescalations (dupes possible)\n", xodcount.hostescalations);
4420 
4421 
4422 	/* duplicate service escalations */
4423 	for(temp_serviceescalation = xodtemplate_serviceescalation_list; temp_serviceescalation != NULL; temp_serviceescalation = temp_serviceescalation->next) {
4424 
4425 		/* skip serviceescalations without enough data */
4426 		if(temp_serviceescalation->servicegroup_name == NULL && temp_serviceescalation->service_description == NULL && (temp_serviceescalation->host_name == NULL || temp_serviceescalation->hostgroup_name == NULL))
4427 			continue;
4428 		if(temp_serviceescalation->register_object == FALSE)
4429 			continue;
4430 
4431 		bitmap_clear(service_map);
4432 
4433 		master_servicelist = NULL;
4434 
4435 		/* get list of services */
4436 		if(xodtemplate_create_service_list(&master_servicelist, service_map, temp_serviceescalation->host_name, temp_serviceescalation->hostgroup_name, temp_serviceescalation->servicegroup_name, temp_serviceescalation->service_description, temp_serviceescalation->_config_file, temp_serviceescalation->_start_line) != OK)
4437 			return ERROR;
4438 
4439 		/* we won't need these anymore */
4440 		my_free(temp_serviceescalation->host_name);
4441 		my_free(temp_serviceescalation->hostgroup_name);
4442 		my_free(temp_serviceescalation->service_description);
4443 		my_free(temp_serviceescalation->servicegroup_name);
4444 
4445 		/* duplicate service escalation entries */
4446 		for(list = master_servicelist; list; list = next) {
4447 			xodtemplate_service *s = (xodtemplate_service *)list->object_ptr;
4448 			next = list->next;
4449 			free(list);
4450 
4451 			if(bitmap_isset(service_map, s->id))
4452 				continue;
4453 
4454 			xodcount.serviceescalations++;
4455 
4456 			/* if this is the last duplication, use the existing entry */
4457 			if(!next) {
4458 				temp_serviceescalation->host_name = s->host_name;
4459 				temp_serviceescalation->service_description = s->service_description;
4460 				continue;
4461 				}
4462 
4463 			/* duplicate service escalation definition */
4464 			result = xodtemplate_duplicate_serviceescalation(temp_serviceescalation, s->host_name, s->service_description);
4465 
4466 			/* exit on error */
4467 			if(result == ERROR) {
4468 				free_objectlist(&next);
4469 				return ERROR;
4470 				}
4471 			}
4472 		}
4473 	timing_point("Created %u serviceescalations (dupes possible)\n", xodcount.serviceescalations);
4474 
4475 
4476 	/****** DUPLICATE HOSTEXTINFO DEFINITIONS WITH ONE OR MORE HOSTGROUP AND/OR HOST NAMES ******/
4477 	for(temp_hostextinfo = xodtemplate_hostextinfo_list; temp_hostextinfo != NULL; temp_hostextinfo = next_he) {
4478 		next_he = temp_hostextinfo->next;
4479 
4480 		/* skip definitions without enough data */
4481 		if(temp_hostextinfo->hostgroup_name == NULL && temp_hostextinfo->host_name == NULL)
4482 			continue;
4483 
4484 		/* get list of hosts */
4485 		master_hostlist = xodtemplate_expand_hostgroups_and_hosts(temp_hostextinfo->hostgroup_name, temp_hostextinfo->host_name, temp_hostextinfo->_config_file, temp_hostextinfo->_start_line);
4486 		if(master_hostlist == NULL) {
4487 			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);
4488 			return ERROR;
4489 			}
4490 
4491 		/* merge this extinfo with every host in the hostgroup/host name list */
4492 		for(list = master_hostlist; list; list = next) {
4493 			xodtemplate_host *h = (xodtemplate_host *)list->object_ptr;
4494 			next = list->next;
4495 			free(list);
4496 
4497 			/* merge it. we ignore errors here */
4498 			xodtemplate_merge_host_extinfo_object(h, temp_hostextinfo);
4499 			}
4500 		/* might as well kill it off early */
4501 		my_free(temp_hostextinfo->template);
4502 		my_free(temp_hostextinfo->name);
4503 		my_free(temp_hostextinfo->notes);
4504 		my_free(temp_hostextinfo->host_name);
4505 		my_free(temp_hostextinfo->hostgroup_name);
4506 		my_free(temp_hostextinfo->notes_url);
4507 		my_free(temp_hostextinfo->action_url);
4508 		my_free(temp_hostextinfo->icon_image);
4509 		my_free(temp_hostextinfo->vrml_image);
4510 		my_free(temp_hostextinfo->statusmap_image);
4511 		my_free(temp_hostextinfo);
4512 		}
4513 	timing_point("Done merging hostextinfo\n");
4514 
4515 
4516 	/****** DUPLICATE SERVICEEXTINFO DEFINITIONS WITH ONE OR MORE HOSTGROUP AND/OR HOST NAMES ******/
4517 	for(temp_serviceextinfo = xodtemplate_serviceextinfo_list; temp_serviceextinfo != NULL; temp_serviceextinfo = next_se) {
4518 		next_se = temp_serviceextinfo->next;
4519 
4520 		/* skip definitions without enough data */
4521 		if(temp_serviceextinfo->service_description == NULL || (temp_serviceextinfo->hostgroup_name == NULL && temp_serviceextinfo->host_name == NULL))
4522 			continue;
4523 
4524 		bitmap_clear(service_map);
4525 		master_servicelist = NULL;
4526 
4527 		/* get list of services */
4528 		if(xodtemplate_create_service_list(&master_servicelist, service_map, temp_serviceextinfo->host_name, temp_serviceextinfo->hostgroup_name, NULL, temp_serviceextinfo->service_description, temp_serviceextinfo->_config_file, temp_serviceextinfo->_start_line) != OK) {
4529 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand services 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);
4530 			return ERROR;
4531 			}
4532 
4533 		/* merge this serviceextinfo with every service in the list */
4534 		for(list = master_servicelist; list; list = next) {
4535 			xodtemplate_service *s = (xodtemplate_service *)list->object_ptr;
4536 			next = list->next;
4537 			free(list);
4538 			if(bitmap_isset(service_map, s->id))
4539 				continue;
4540 			xodtemplate_merge_service_extinfo_object(s, temp_serviceextinfo);
4541 			}
4542 		/* now we're done, so we might as well kill it off */
4543 		my_free(temp_serviceextinfo->template);
4544 		my_free(temp_serviceextinfo->name);
4545 		my_free(temp_serviceextinfo->host_name);
4546 		my_free(temp_serviceextinfo->hostgroup_name);
4547 		my_free(temp_serviceextinfo->service_description);
4548 		my_free(temp_serviceextinfo->notes);
4549 		my_free(temp_serviceextinfo->notes_url);
4550 		my_free(temp_serviceextinfo->action_url);
4551 		my_free(temp_serviceextinfo->icon_image);
4552 		my_free(temp_serviceextinfo->icon_image_alt);
4553 		my_free(temp_serviceextinfo);
4554 		}
4555 	timing_point("Done merging serviceextinfo\n");
4556 
4557 	return OK;
4558 	}
4559 
4560 
4561 
4562 /* duplicates a service definition (with a new host name) */
xodtemplate_duplicate_service(xodtemplate_service * temp_service,char * host_name,int from_hg)4563 int xodtemplate_duplicate_service(xodtemplate_service *temp_service, char *host_name, int from_hg) {
4564 	xodtemplate_service *new_service = NULL;
4565 	int error = FALSE;
4566 
4567 	/* allocate zero'd out memory for a new service definition */
4568 	new_service = (xodtemplate_service *)calloc(1, sizeof(xodtemplate_service));
4569 	if(new_service == NULL)
4570 		return ERROR;
4571 
4572 	/* copy the entire thing and override what we have to */
4573 	memcpy(new_service, temp_service, sizeof(*new_service));
4574 	new_service->is_copy = TRUE;
4575 	new_service->id = xodcount.services++;
4576 	new_service->host_name = host_name;
4577 
4578 	/* tag service apply on host group */
4579 	new_service->is_from_hostgroup = from_hg;
4580 
4581 	/* allocate memory for and copy string members of service definition (host name provided, DO NOT duplicate hostgroup member!)*/
4582 	if(temp_service->service_groups != NULL && (new_service->service_groups = (char *)strdup(temp_service->service_groups)) == NULL)
4583 		error = TRUE;
4584 	if(temp_service->contact_groups != NULL && (new_service->contact_groups = (char *)strdup(temp_service->contact_groups)) == NULL)
4585 		error = TRUE;
4586 	if(temp_service->contacts != NULL && (new_service->contacts = (char *)strdup(temp_service->contacts)) == NULL)
4587 		error = TRUE;
4588 
4589 	if(error == TRUE) {
4590 		my_free(new_service->service_groups);
4591 		my_free(new_service->contact_groups);
4592 		my_free(new_service->contacts);
4593 		my_free(new_service);
4594 		return ERROR;
4595 		}
4596 
4597 	/* add new service to head of list in memory */
4598 	new_service->next = xodtemplate_service_list;
4599 	xodtemplate_service_list = new_service;
4600 
4601 	return OK;
4602 	}
4603 
4604 
4605 
4606 
4607 /* duplicates a host escalation definition (with a new host name) */
xodtemplate_duplicate_hostescalation(xodtemplate_hostescalation * temp_hostescalation,char * host_name)4608 int xodtemplate_duplicate_hostescalation(xodtemplate_hostescalation *temp_hostescalation, char *host_name) {
4609 	xodtemplate_hostescalation *new_hostescalation = NULL;
4610 	int error = FALSE;
4611 
4612 
4613 	/* allocate zero'd out memory for a new host escalation definition */
4614 	new_hostescalation = (xodtemplate_hostescalation *)calloc(1, sizeof(xodtemplate_hostescalation));
4615 	if(new_hostescalation == NULL)
4616 		return ERROR;
4617 
4618 	memcpy(new_hostescalation, temp_hostescalation, sizeof(*new_hostescalation));
4619 	new_hostescalation->is_copy = TRUE;
4620 
4621 	new_hostescalation->host_name = host_name;
4622 
4623 	if(temp_hostescalation->contact_groups != NULL && (new_hostescalation->contact_groups = (char *)strdup(temp_hostescalation->contact_groups)) == NULL)
4624 		error = TRUE;
4625 	if(temp_hostescalation->contacts != NULL && (new_hostescalation->contacts = (char *)strdup(temp_hostescalation->contacts)) == NULL)
4626 		error = TRUE;
4627 
4628 	if(error == TRUE) {
4629 		my_free(new_hostescalation->contact_groups);
4630 		my_free(new_hostescalation->contacts);
4631 		my_free(new_hostescalation);
4632 		return ERROR;
4633 		}
4634 
4635 	/* add new hostescalation to head of list in memory */
4636 	new_hostescalation->next = xodtemplate_hostescalation_list;
4637 	xodtemplate_hostescalation_list = new_hostescalation;
4638 
4639 	return OK;
4640 	}
4641 
4642 
4643 
4644 /* 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)4645 int xodtemplate_duplicate_serviceescalation(xodtemplate_serviceescalation *temp_serviceescalation, char *host_name, char *svc_description) {
4646 	xodtemplate_serviceescalation *new_serviceescalation = NULL;
4647 	int error = FALSE;
4648 
4649 	/* allocate zero'd out memory for a new service escalation definition */
4650 	new_serviceescalation = (xodtemplate_serviceescalation *)calloc(1, sizeof(xodtemplate_serviceescalation));
4651 	if(new_serviceescalation == NULL)
4652 		return ERROR;
4653 
4654 	memcpy(new_serviceescalation, temp_serviceescalation, sizeof(*new_serviceescalation));
4655 	new_serviceescalation->is_copy = TRUE;
4656 	new_serviceescalation->host_name = host_name;
4657 	new_serviceescalation->service_description = svc_description;
4658 
4659 	if(temp_serviceescalation->contact_groups != NULL && (new_serviceescalation->contact_groups = (char *)strdup(temp_serviceescalation->contact_groups)) == NULL)
4660 		error = TRUE;
4661 	if(temp_serviceescalation->contacts != NULL && (new_serviceescalation->contacts = (char *)strdup(temp_serviceescalation->contacts)) == NULL)
4662 		error = TRUE;
4663 
4664 	if(error == TRUE) {
4665 		my_free(new_serviceescalation->contact_groups);
4666 		my_free(new_serviceescalation->contacts);
4667 		my_free(new_serviceescalation);
4668 		return ERROR;
4669 		}
4670 
4671 	/* add new serviceescalation to head of list in memory */
4672 	new_serviceescalation->next = xodtemplate_serviceescalation_list;
4673 	xodtemplate_serviceescalation_list = new_serviceescalation;
4674 
4675 	return OK;
4676 	}
4677 
4678 /******************************************************************/
4679 /***************** OBJECT RESOLUTION FUNCTIONS ********************/
4680 /******************************************************************/
4681 
4682 
4683 /* inherit object properties */
4684 /* some missing defaults (notification options, etc.) are also applied here */
xodtemplate_inherit_object_properties(void)4685 int xodtemplate_inherit_object_properties(void) {
4686 	xodtemplate_host *temp_host = NULL;
4687 	xodtemplate_service *temp_service = NULL;
4688 	xodtemplate_serviceescalation *temp_serviceescalation = NULL;
4689 	xodtemplate_hostescalation *temp_hostescalation = NULL;
4690 
4691 
4692 	/* fill in missing defaults for hosts... */
4693 	for(temp_host = xodtemplate_host_list; temp_host != NULL; temp_host = temp_host->next) {
4694 
4695 		/* if notification options are missing, assume all */
4696 		if(temp_host->have_notification_options == FALSE) {
4697 			temp_host->notification_options = OPT_ALL;
4698 			temp_host->have_notification_options = TRUE;
4699 			}
4700 		}
4701 
4702 	/* services inherit some properties from their associated host... */
4703 	for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) {
4704 
4705 		/* find the host */
4706 		if((temp_host = xodtemplate_find_real_host(temp_service->host_name)) == NULL)
4707 			continue;
4708 
4709 		/*
4710 		 * if the service has no contacts specified, it will inherit
4711 		 * them from the host
4712 		 */
4713 		if(temp_service->have_contact_groups == FALSE && temp_service->have_contacts == FALSE) {
4714 			xod_inherit_str(temp_service, temp_host, contact_groups);
4715 			xod_inherit_str(temp_service, temp_host, contacts);
4716 			}
4717 
4718 		/* services inherit notification interval from host if not already specified */
4719 		xod_inherit(temp_service, temp_host, notification_interval);
4720 
4721 		/* services inherit notification period from host if not already specified */
4722 		xod_inherit_str(temp_service, temp_host, notification_period);
4723 
4724 		/* if notification options are missing, assume all */
4725 		if(temp_service->have_notification_options == FALSE) {
4726 			temp_service->notification_options = OPT_ALL;
4727 			temp_service->have_notification_options = TRUE;
4728 			}
4729 		}
4730 
4731 	/* service escalations inherit some properties from their associated service... */
4732 	for(temp_serviceescalation = xodtemplate_serviceescalation_list; temp_serviceescalation != NULL; temp_serviceescalation = temp_serviceescalation->next) {
4733 
4734 		/* find the service */
4735 		if((temp_service = xodtemplate_find_real_service(temp_serviceescalation->host_name, temp_serviceescalation->service_description)) == NULL)
4736 			continue;
4737 
4738 		/* SPECIAL RULE 10/04/07 - additive inheritance from service's contactgroup(s) */
4739 		if(temp_serviceescalation->contact_groups != NULL && temp_serviceescalation->contact_groups[0] == '+')
4740 			xodtemplate_get_inherited_string(&temp_service->have_contact_groups, &temp_service->contact_groups, &temp_serviceescalation->have_contact_groups, &temp_serviceescalation->contact_groups);
4741 
4742 		/* SPECIAL RULE 10/04/07 - additive inheritance from service's contact(s) */
4743 		if(temp_serviceescalation->contacts != NULL && temp_serviceescalation->contacts[0] == '+')
4744 			xodtemplate_get_inherited_string(&temp_service->have_contacts, &temp_service->contacts, &temp_serviceescalation->have_contacts, &temp_serviceescalation->contacts);
4745 
4746 		/* service escalations inherit contacts from service if none are specified */
4747 		if(temp_serviceescalation->have_contact_groups == FALSE && temp_serviceescalation->have_contacts == FALSE) {
4748 			xod_inherit_str(temp_serviceescalation, temp_service, contact_groups);
4749 			xod_inherit_str(temp_serviceescalation, temp_service, contacts);
4750 			}
4751 
4752 		/* service escalations inherit notification interval from service if not already defined */
4753 		xod_inherit(temp_serviceescalation, temp_service, notification_interval);
4754 
4755 		/* service escalations inherit escalation period from service if not already defined */
4756 		if(temp_serviceescalation->have_escalation_period == FALSE && temp_service->have_notification_period == TRUE && temp_service->notification_period != NULL) {
4757 			temp_serviceescalation->escalation_period = (char *)strdup(temp_service->notification_period);
4758 			temp_serviceescalation->have_escalation_period = TRUE;
4759 			}
4760 
4761 		/* if escalation options are missing, assume all */
4762 		if(temp_serviceescalation->have_escalation_options == FALSE) {
4763 			temp_serviceescalation->escalation_options = OPT_ALL;
4764 			temp_serviceescalation->have_escalation_options = TRUE;
4765 			}
4766 
4767 		/* 03/05/08 clear additive string chars - not done in xodtemplate_clean_additive_strings() anymore */
4768 		xodtemplate_clean_additive_string(&temp_serviceescalation->contact_groups);
4769 		xodtemplate_clean_additive_string(&temp_serviceescalation->contacts);
4770 		}
4771 
4772 	/* host escalations inherit some properties from their associated host... */
4773 	for(temp_hostescalation = xodtemplate_hostescalation_list; temp_hostescalation != NULL; temp_hostescalation = temp_hostescalation->next) {
4774 
4775 		/* find the host */
4776 		if((temp_host = xodtemplate_find_real_host(temp_hostescalation->host_name)) == NULL)
4777 			continue;
4778 
4779 		/* SPECIAL RULE 10/04/07 - additive inheritance from host's contactgroup(s) */
4780 		if(temp_hostescalation->contact_groups != NULL && temp_hostescalation->contact_groups[0] == '+')
4781 			xodtemplate_get_inherited_string(&temp_host->have_contact_groups, &temp_host->contact_groups, &temp_hostescalation->have_contact_groups, &temp_hostescalation->contact_groups);
4782 
4783 		/* SPECIAL RULE 10/04/07 - additive inheritance from host's contact(s) */
4784 		if(temp_hostescalation->contacts != NULL && temp_hostescalation->contacts[0] == '+')
4785 			xodtemplate_get_inherited_string(&temp_host->have_contacts, &temp_host->contacts, &temp_hostescalation->have_contacts, &temp_hostescalation->contacts);
4786 
4787 		/* host escalations inherit contacts from host if none are specified */
4788 		if(temp_hostescalation->have_contact_groups == FALSE && temp_hostescalation->have_contacts == FALSE) {
4789 			xod_inherit_str(temp_hostescalation, temp_host, contact_groups);
4790 			xod_inherit_str(temp_hostescalation, temp_host, contacts);
4791 			}
4792 
4793 		/* host escalations inherit notification interval from host if not already defined */
4794 		xod_inherit(temp_hostescalation, temp_host, notification_interval);
4795 
4796 		/* host escalations inherit escalation period from host if not already defined */
4797 		if(temp_hostescalation->have_escalation_period == FALSE && temp_host->have_notification_period == TRUE && temp_host->notification_period != NULL) {
4798 			temp_hostescalation->escalation_period = (char *)strdup(temp_host->notification_period);
4799 			temp_hostescalation->have_escalation_period = TRUE;
4800 			}
4801 
4802 		/* if escalation options are missing, assume all */
4803 		if(temp_hostescalation->have_escalation_options == FALSE) {
4804 			temp_hostescalation->escalation_options = OPT_ALL;
4805 			temp_hostescalation->have_escalation_options = TRUE;
4806 			}
4807 
4808 		/* 03/05/08 clear additive string chars - not done in xodtemplate_clean_additive_strings() anymore */
4809 		xodtemplate_clean_additive_string(&temp_hostescalation->contact_groups);
4810 		xodtemplate_clean_additive_string(&temp_hostescalation->contacts);
4811 		}
4812 
4813 	return OK;
4814 	}
4815 
4816 #endif
4817 
4818 
4819 /******************************************************************/
4820 /***************** OBJECT RESOLUTION FUNCTIONS ********************/
4821 /******************************************************************/
4822 
xodtemplate_register_and_destroy_hostescalation(void * he_)4823 static int xodtemplate_register_and_destroy_hostescalation(void *he_)
4824 {
4825 	xodtemplate_hostescalation *he = (xodtemplate_hostescalation *)he_;
4826 	int result;
4827 
4828 	result = xodtemplate_register_hostescalation(he);
4829 	if(he->is_copy == FALSE) {
4830 		my_free(he->escalation_period);
4831 		}
4832 	my_free(he->contact_groups);
4833 	my_free(he->contacts);
4834 	my_free(he);
4835 
4836 	return result;
4837 }
4838 
xodtemplate_register_and_destroy_serviceescalation(void * se_)4839 static int xodtemplate_register_and_destroy_serviceescalation(void *se_)
4840 {
4841 	xodtemplate_serviceescalation *se = (xodtemplate_serviceescalation *)se_;
4842 	int result;
4843 	result = xodtemplate_register_serviceescalation(se);
4844 
4845 	if(se->is_copy == FALSE)
4846 		my_free(se->escalation_period);
4847 
4848 	my_free(se->contact_groups);
4849 	my_free(se->contacts);
4850 	my_free(se);
4851 
4852 	return result;
4853 }
4854 
4855 #ifndef NSCGI
xodtemplate_register_and_destroy_hostdependency(void * hd_)4856 static int xodtemplate_register_and_destroy_hostdependency(void *hd_)
4857 {
4858 	xodtemplate_hostdependency *temp_hostdependency = (xodtemplate_hostdependency *)hd_;
4859 	objectlist *master_hostlist = NULL, *dependent_hostlist = NULL;
4860 	objectlist *list, *next, *l2;
4861 
4862 	/* skip host dependencies without enough data */
4863 	if(temp_hostdependency->hostgroup_name == NULL && temp_hostdependency->dependent_hostgroup_name == NULL && temp_hostdependency->host_name == NULL && temp_hostdependency->dependent_host_name == NULL)
4864 		return OK;
4865 
4866 	/* get list of master host names */
4867 	master_hostlist = xodtemplate_expand_hostgroups_and_hosts(temp_hostdependency->hostgroup_name, temp_hostdependency->host_name, temp_hostdependency->_config_file, temp_hostdependency->_start_line);
4868 	if(master_hostlist == NULL && allow_empty_hostgroup_assignment==0) {
4869 		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);
4870 		return ERROR;
4871 		}
4872 
4873 	/* get list of dependent host names */
4874 	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);
4875 	if(dependent_hostlist == NULL && allow_empty_hostgroup_assignment==0) {
4876 		logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand dependent hostgroups (%s) and/or hosts (%s) specified in host dependency (config file '%s', starting on line %d)\n", temp_hostdependency->dependent_hostgroup_name, temp_hostdependency->dependent_host_name, xodtemplate_config_file_name(temp_hostdependency->_config_file), temp_hostdependency->_start_line);
4877 		free_objectlist(&master_hostlist);
4878 		return ERROR;
4879 		}
4880 
4881 	my_free(temp_hostdependency->name);
4882 	my_free(temp_hostdependency->template);
4883 	my_free(temp_hostdependency->host_name);
4884 	my_free(temp_hostdependency->hostgroup_name);
4885 	my_free(temp_hostdependency->dependent_host_name);
4886 	my_free(temp_hostdependency->dependent_hostgroup_name);
4887 
4888 	/* duplicate the dependency definitions */
4889 	for(list = master_hostlist; list; list = next) {
4890 		xodtemplate_host *master = (xodtemplate_host *)list->object_ptr;
4891 		next = list->next;
4892 		free(list);
4893 
4894 		for(l2 = dependent_hostlist; l2; l2 = l2->next) {
4895 			xodtemplate_host *child = (xodtemplate_host *)l2->object_ptr;
4896 
4897 			temp_hostdependency->host_name = master->host_name;
4898 			temp_hostdependency->dependent_host_name = child->host_name;
4899 			if(xodtemplate_register_hostdependency(temp_hostdependency) != OK) {
4900 				/* exit on error */
4901 				free_objectlist(&dependent_hostlist);
4902 				free_objectlist(&next);
4903 				return ERROR;
4904 				}
4905 			}
4906 		}
4907 
4908 	free_objectlist(&dependent_hostlist);
4909 	my_free(temp_hostdependency->dependency_period);
4910 	my_free(temp_hostdependency);
4911 
4912 	return OK;
4913 }
4914 
xodtemplate_register_and_destroy_servicedependency(void * sd_)4915 static int xodtemplate_register_and_destroy_servicedependency(void *sd_)
4916 {
4917 	objectlist *parents = NULL, *plist, *pnext;
4918 	objectlist *children = NULL, *clist;
4919 	xodtemplate_servicedependency *temp_servicedependency = (xodtemplate_servicedependency *)sd_;
4920 	int same_host = FALSE, children_first = FALSE, pret = OK, cret = OK;
4921 	char *hname, *sdesc, *dhname, *dsdesc;
4922 
4923 	hname = temp_servicedependency->host_name;
4924 	sdesc = temp_servicedependency->service_description;
4925 	dhname = temp_servicedependency->dependent_host_name;
4926 	dsdesc = temp_servicedependency->dependent_service_description;
4927 
4928 	my_free(temp_servicedependency->name);
4929 	my_free(temp_servicedependency->template);
4930 
4931 	/* skip templates, but free them first */
4932 	if(temp_servicedependency->register_object == 0) {
4933 		my_free(temp_servicedependency->host_name);
4934 		my_free(temp_servicedependency->service_description);
4935 		my_free(temp_servicedependency->hostgroup_name);
4936 		my_free(temp_servicedependency->dependent_host_name);
4937 		my_free(temp_servicedependency->dependent_service_description);
4938 		my_free(temp_servicedependency->dependent_hostgroup_name);
4939 		return OK;
4940 		}
4941 
4942 	if(!temp_servicedependency->host_name && !temp_servicedependency->hostgroup_name
4943 	   && !temp_servicedependency->servicegroup_name)
4944 	{
4945 		/*
4946 		 * parent service is in exact. We must take children first
4947 		 * and build parent chain from same-host deps there
4948 		 */
4949 		children_first = TRUE;
4950 		same_host = TRUE;
4951 	}
4952 
4953 	/* take care of same-host dependencies */
4954 	if(!temp_servicedependency->dependent_host_name && !temp_servicedependency->dependent_hostgroup_name) {
4955 		if (!temp_servicedependency->dependent_servicegroup_name) {
4956 			if (children_first || !temp_servicedependency->dependent_service_description) {
4957 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Impossible service dependency definition\n (config file '%s', starting at line '%d')",
4958 					  xodtemplate_config_file_name(temp_servicedependency->_config_file),
4959 					  temp_servicedependency->_start_line);
4960 				return ERROR;
4961 			}
4962 			same_host = TRUE;
4963 		}
4964 	}
4965 
4966 	parents = children = NULL;
4967 	bitmap_clear(parent_map);
4968 	bitmap_clear(service_map);
4969 
4970 	/* create the two object lists */
4971 	if(!children_first) {
4972 		pret = xodtemplate_create_service_list(&parents, parent_map, temp_servicedependency->host_name, temp_servicedependency->hostgroup_name, temp_servicedependency->servicegroup_name, temp_servicedependency->service_description, temp_servicedependency->_config_file, temp_servicedependency->_start_line);
4973 		if (!same_host)
4974 			cret = xodtemplate_create_service_list(&children, service_map, temp_servicedependency->dependent_host_name, temp_servicedependency->dependent_hostgroup_name, temp_servicedependency->dependent_servicegroup_name, temp_servicedependency->dependent_service_description, temp_servicedependency->_config_file, temp_servicedependency->_start_line);
4975 	} else {
4976 		/*
4977 		 * NOTE: we flip the variables here to avoid duplicating
4978 		 * the entire loop down below
4979 		 */
4980 		cret = xodtemplate_create_service_list(&parents, parent_map, temp_servicedependency->dependent_host_name, temp_servicedependency->dependent_hostgroup_name, temp_servicedependency->dependent_servicegroup_name, temp_servicedependency->dependent_service_description, temp_servicedependency->_config_file, temp_servicedependency->_start_line);
4981 		dsdesc = temp_servicedependency->service_description;
4982 		sdesc = temp_servicedependency->dependent_service_description;
4983 	}
4984 
4985 	/* now log errors and bail out if we failed to get members */
4986 	if(pret != OK) {
4987 		logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand master service(s) (config file '%s', starting at line %d)\n",
4988 			  xodtemplate_config_file_name(temp_servicedependency->_config_file),
4989 			  temp_servicedependency->_start_line);
4990 		}
4991 	if(cret != OK) {
4992 		logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand dependent service(s) (at config file '%s', starting on line %d)\n",
4993 			  xodtemplate_config_file_name(temp_servicedependency->_config_file),
4994 			  temp_servicedependency->_start_line);
4995 		}
4996 
4997 	if(cret != OK || pret != OK)
4998 		return ERROR;
4999 
5000 	/*
5001 	 * every service in "children" depends on every service in
5002 	 * "parents", so just loop twice and create them all.
5003 	 */
5004 	for(plist = parents; plist; plist = pnext) {
5005 		xodtemplate_service *p = (xodtemplate_service *)plist->object_ptr;
5006 		pnext = plist->next;
5007 		free(plist); /* free it as we go along */
5008 
5009 		if(bitmap_isset(parent_map, p->id))
5010 			continue;
5011 		bitmap_set(parent_map, p->id);
5012 
5013         bitmap_clear(service_map);
5014 
5015 
5016 		/*
5017 		 * if this is a same-host dependency, we must expand
5018 		 * dependent_service_description for the host we're
5019 		 * currently looking at
5020 		 */
5021 		if(same_host) {
5022 			children = NULL;
5023 			if(xodtemplate_expand_services(&children, service_map, p->host_name, dsdesc, temp_servicedependency->_config_file, temp_servicedependency->_start_line) != OK) {
5024 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Failed to expand same-host servicedependency services (config file '%s', starting at line %d)\n",
5025 					  xodtemplate_config_file_name(temp_servicedependency->_config_file),
5026 					  temp_servicedependency->_start_line);
5027 				return ERROR;
5028 			}
5029 		}
5030 
5031 		for(clist = children; clist; clist = clist->next) {
5032 			xodtemplate_service *c = (xodtemplate_service *)clist->object_ptr;
5033 			if(bitmap_isset(service_map, c->id))
5034 				continue;
5035 			bitmap_set(service_map, c->id);
5036 
5037 			/* now register, but flip the states again if necessary */
5038 			if(children_first) {
5039 				xodtemplate_service *tmp = p;
5040 				p = c;
5041 				c = tmp;
5042 			}
5043 			temp_servicedependency->host_name = p->host_name;
5044 			temp_servicedependency->service_description = p->service_description;
5045 			temp_servicedependency->dependent_host_name = c->host_name;
5046 			temp_servicedependency->dependent_service_description = c->service_description;
5047 			if(xodtemplate_register_servicedependency(temp_servicedependency) != OK) {
5048 				logit(NSLOG_VERIFICATION_WARNING, TRUE, "Error: Failed to register servicedependency from '%s;%s' to '%s;%s' (config file '%s', starting at line %d)\n",
5049 					  p->host_name, p->service_description,
5050 					  c->host_name, c->service_description,
5051 					  xodtemplate_config_file_name(temp_servicedependency->_config_file), temp_servicedependency->_start_line);
5052 				return ERROR;
5053 			}
5054 		}
5055 		if(same_host == TRUE)
5056 			free_objectlist(&children);
5057 	}
5058 	if(same_host == FALSE)
5059 		free_objectlist(&children);
5060 
5061 	my_free(hname);
5062 	my_free(sdesc);
5063 	my_free(dhname);
5064 	my_free(dsdesc);
5065 	my_free(temp_servicedependency->hostgroup_name);
5066 	my_free(temp_servicedependency->servicegroup_name);
5067 	my_free(temp_servicedependency->dependent_hostgroup_name);
5068 	my_free(temp_servicedependency->dependent_servicegroup_name);
5069 	my_free(temp_servicedependency->dependency_period);
5070 	my_free(temp_servicedependency);
5071 	return OK;
5072 }
5073 
5074 
5075 /* resolves object definitions */
xodtemplate_resolve_objects(void)5076 int xodtemplate_resolve_objects(void) {
5077 	xodtemplate_timeperiod *temp_timeperiod = NULL;
5078 	xodtemplate_command *temp_command = NULL;
5079 	xodtemplate_contactgroup *temp_contactgroup = NULL;
5080 	xodtemplate_hostgroup *temp_hostgroup = NULL;
5081 	xodtemplate_servicegroup *temp_servicegroup = NULL;
5082 	xodtemplate_servicedependency *temp_servicedependency = NULL;
5083 	xodtemplate_serviceescalation *temp_serviceescalation = NULL;
5084 	xodtemplate_contact *temp_contact = NULL;
5085 	xodtemplate_host *temp_host = NULL;
5086 	xodtemplate_service *temp_service = NULL;
5087 	xodtemplate_hostdependency *temp_hostdependency = NULL;
5088 	xodtemplate_hostescalation *temp_hostescalation = NULL;
5089 	xodtemplate_hostextinfo *temp_hostextinfo = NULL;
5090 	xodtemplate_serviceextinfo *temp_serviceextinfo = NULL;
5091 
5092 	/* resolve all timeperiod objects */
5093 	for(temp_timeperiod = xodtemplate_timeperiod_list; temp_timeperiod != NULL; temp_timeperiod = temp_timeperiod->next) {
5094 		if(xodtemplate_resolve_timeperiod(temp_timeperiod) == ERROR)
5095 			return ERROR;
5096 		}
5097 
5098 	/* resolve all command objects */
5099 	for(temp_command = xodtemplate_command_list; temp_command != NULL; temp_command = temp_command->next) {
5100 		if(xodtemplate_resolve_command(temp_command) == ERROR)
5101 			return ERROR;
5102 		}
5103 
5104 	/* resolve all contactgroup objects */
5105 	for(temp_contactgroup = xodtemplate_contactgroup_list; temp_contactgroup != NULL; temp_contactgroup = temp_contactgroup->next) {
5106 		if(xodtemplate_resolve_contactgroup(temp_contactgroup) == ERROR)
5107 			return ERROR;
5108 		}
5109 
5110 	/* resolve all hostgroup objects */
5111 	for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) {
5112 		if(xodtemplate_resolve_hostgroup(temp_hostgroup) == ERROR)
5113 			return ERROR;
5114 		}
5115 
5116 	/* resolve all servicegroup objects */
5117 	for(temp_servicegroup = xodtemplate_servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) {
5118 		if(xodtemplate_resolve_servicegroup(temp_servicegroup) == ERROR)
5119 			return ERROR;
5120 		}
5121 
5122 	/* resolve all servicedependency objects */
5123 	for(temp_servicedependency = xodtemplate_servicedependency_list; temp_servicedependency != NULL; temp_servicedependency = temp_servicedependency->next) {
5124 		if(xodtemplate_resolve_servicedependency(temp_servicedependency) == ERROR)
5125 			return ERROR;
5126 		}
5127 
5128 	/* resolve all serviceescalation objects */
5129 	for(temp_serviceescalation = xodtemplate_serviceescalation_list; temp_serviceescalation != NULL; temp_serviceescalation = temp_serviceescalation->next) {
5130 		if(xodtemplate_resolve_serviceescalation(temp_serviceescalation) == ERROR)
5131 			return ERROR;
5132 		}
5133 
5134 	/* resolve all contact objects */
5135 	for(temp_contact = xodtemplate_contact_list; temp_contact != NULL; temp_contact = temp_contact->next) {
5136 		if(xodtemplate_resolve_contact(temp_contact) == ERROR)
5137 			return ERROR;
5138 		}
5139 
5140 	/* resolve all host objects */
5141 	for(temp_host = xodtemplate_host_list; temp_host != NULL; temp_host = temp_host->next) {
5142 		if(xodtemplate_resolve_host(temp_host) == ERROR)
5143 			return ERROR;
5144 		}
5145 
5146 	/* resolve all service objects */
5147 	for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) {
5148 		if(xodtemplate_resolve_service(temp_service) == ERROR)
5149 			return ERROR;
5150 		}
5151 
5152 	/* resolve all hostdependency objects */
5153 	for(temp_hostdependency = xodtemplate_hostdependency_list; temp_hostdependency != NULL; temp_hostdependency = temp_hostdependency->next) {
5154 		if(xodtemplate_resolve_hostdependency(temp_hostdependency) == ERROR)
5155 			return ERROR;
5156 		}
5157 
5158 	/* resolve all hostescalation objects */
5159 	for(temp_hostescalation = xodtemplate_hostescalation_list; temp_hostescalation != NULL; temp_hostescalation = temp_hostescalation->next) {
5160 		if(xodtemplate_resolve_hostescalation(temp_hostescalation) == ERROR)
5161 			return ERROR;
5162 		}
5163 
5164 	/* resolve all hostextinfo objects */
5165 	for(temp_hostextinfo = xodtemplate_hostextinfo_list; temp_hostextinfo != NULL; temp_hostextinfo = temp_hostextinfo->next) {
5166 		if(xodtemplate_resolve_hostextinfo(temp_hostextinfo) == ERROR)
5167 			return ERROR;
5168 		}
5169 
5170 	/* resolve all serviceextinfo objects */
5171 	for(temp_serviceextinfo = xodtemplate_serviceextinfo_list; temp_serviceextinfo != NULL; temp_serviceextinfo = temp_serviceextinfo->next) {
5172 		if(xodtemplate_resolve_serviceextinfo(temp_serviceextinfo) == ERROR)
5173 			return ERROR;
5174 		}
5175 
5176 	return OK;
5177 	}
5178 
5179 /* resolves a timeperiod object */
xodtemplate_resolve_timeperiod(xodtemplate_timeperiod * this_timeperiod)5180 int xodtemplate_resolve_timeperiod(xodtemplate_timeperiod *this_timeperiod) {
5181 	char *temp_ptr = NULL;
5182 	char *template_names = NULL;
5183 	char *template_name_ptr = NULL;
5184 	xodtemplate_daterange *template_daterange = NULL;
5185 	xodtemplate_daterange *this_daterange = NULL;
5186 	xodtemplate_daterange *new_daterange = NULL;
5187 	xodtemplate_timeperiod *template_timeperiod = NULL;
5188 	int x;
5189 
5190 	/* return if this timeperiod has already been resolved */
5191 	if(this_timeperiod->has_been_resolved == TRUE)
5192 		return OK;
5193 
5194 	/* set the resolved flag */
5195 	this_timeperiod->has_been_resolved = TRUE;
5196 
5197 	/* return if we have no template */
5198 	if(this_timeperiod->template == NULL)
5199 		return OK;
5200 
5201 	if((template_names = (char *)strdup(this_timeperiod->template)) == NULL)
5202 		return ERROR;
5203 
5204 	/* apply all templates */
5205 	template_name_ptr = template_names;
5206 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
5207 
5208 		template_timeperiod = xodtemplate_find_timeperiod(temp_ptr);
5209 		if(template_timeperiod == NULL) {
5210 			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);
5211 			my_free(template_names);
5212 			return ERROR;
5213 			}
5214 
5215 		/* resolve the template timeperiod... */
5216 		xodtemplate_resolve_timeperiod(template_timeperiod);
5217 
5218 		/* apply missing properties from template timeperiod... */
5219 		xod_inherit_str_nohave(this_timeperiod, template_timeperiod, timeperiod_name);
5220 		xod_inherit_str_nohave(this_timeperiod, template_timeperiod, alias);
5221 		xod_inherit_str_nohave(this_timeperiod, template_timeperiod, exclusions);
5222 		for(x = 0; x < 7; x++)
5223 			xod_inherit_str_nohave(this_timeperiod, template_timeperiod, timeranges[x]);
5224 
5225 		/* daterange exceptions require more work to apply missing ranges... */
5226 		for(x = 0; x < DATERANGE_TYPES; x++) {
5227 			for(template_daterange = template_timeperiod->exceptions[x]; template_daterange != NULL; template_daterange = template_daterange->next) {
5228 
5229 				/* see if this same daterange already exists in the timeperiod */
5230 				for(this_daterange = this_timeperiod->exceptions[x]; this_daterange != NULL; this_daterange = this_daterange->next) {
5231 					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))
5232 						break;
5233 					}
5234 
5235 				/* this daterange already exists in the timeperiod, so don't inherit it */
5236 				if(this_daterange != NULL)
5237 					continue;
5238 
5239 				/* inherit the daterange from the template */
5240 				if((new_daterange = (xodtemplate_daterange *)malloc(sizeof(xodtemplate_daterange))) == NULL)
5241 					continue;
5242 				new_daterange->type = template_daterange->type;
5243 				new_daterange->syear = template_daterange->syear;
5244 				new_daterange->smon = template_daterange->smon;
5245 				new_daterange->smday = template_daterange->smday;
5246 				new_daterange->swday = template_daterange->swday;
5247 				new_daterange->swday_offset = template_daterange->swday_offset;
5248 				new_daterange->eyear = template_daterange->eyear;
5249 				new_daterange->emon = template_daterange->emon;
5250 				new_daterange->emday = template_daterange->emday;
5251 				new_daterange->ewday = template_daterange->ewday;
5252 				new_daterange->ewday_offset = template_daterange->ewday_offset;
5253 				new_daterange->skip_interval = template_daterange->skip_interval;
5254 				new_daterange->timeranges = NULL;
5255 				if(template_daterange->timeranges != NULL)
5256 					new_daterange->timeranges = (char *)strdup(template_daterange->timeranges);
5257 
5258 				/* add new daterange to head of list (should it be added to the end instead?) */
5259 				new_daterange->next = this_timeperiod->exceptions[x];
5260 				this_timeperiod->exceptions[x] = new_daterange;
5261 				}
5262 			}
5263 		}
5264 
5265 	my_free(template_names);
5266 
5267 	return OK;
5268 	}
5269 
5270 
5271 
5272 
5273 /* resolves a command object */
xodtemplate_resolve_command(xodtemplate_command * this_command)5274 int xodtemplate_resolve_command(xodtemplate_command *this_command) {
5275 	char *temp_ptr = NULL;
5276 	char *template_names = NULL;
5277 	char *template_name_ptr = NULL;
5278 	xodtemplate_command *template_command = NULL;
5279 
5280 	/* return if this command has already been resolved */
5281 	if(this_command->has_been_resolved == TRUE)
5282 		return OK;
5283 
5284 	/* set the resolved flag */
5285 	this_command->has_been_resolved = TRUE;
5286 
5287 	/* return if we have no template */
5288 	if(this_command->template == NULL)
5289 		return OK;
5290 
5291 	if((template_names = (char *)strdup(this_command->template)) == NULL)
5292 		return ERROR;
5293 
5294 	/* apply all templates */
5295 	template_name_ptr = template_names;
5296 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
5297 
5298 		template_command = xodtemplate_find_command(temp_ptr);
5299 		if(template_command == NULL) {
5300 			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);
5301 			my_free(template_names);
5302 			return ERROR;
5303 			}
5304 
5305 		/* resolve the template command... */
5306 		xodtemplate_resolve_command(template_command);
5307 
5308 		/* apply missing properties from template command... */
5309 		xod_inherit_str_nohave(this_command, template_command, command_name);
5310 		xod_inherit_str_nohave(this_command, template_command, command_line);
5311 		}
5312 
5313 	my_free(template_names);
5314 
5315 	return OK;
5316 	}
5317 
5318 
5319 
5320 
5321 /* resolves a contactgroup object */
xodtemplate_resolve_contactgroup(xodtemplate_contactgroup * this_contactgroup)5322 int xodtemplate_resolve_contactgroup(xodtemplate_contactgroup *this_contactgroup) {
5323 	char *temp_ptr = NULL;
5324 	char *template_names = NULL;
5325 	char *template_name_ptr = NULL;
5326 	xodtemplate_contactgroup *template_contactgroup = NULL;
5327 
5328 	/* return if this contactgroup has already been resolved */
5329 	if(this_contactgroup->has_been_resolved == TRUE)
5330 		return OK;
5331 
5332 	/* set the resolved flag */
5333 	this_contactgroup->has_been_resolved = TRUE;
5334 
5335 	/* return if we have no template */
5336 	if(this_contactgroup->template == NULL)
5337 		return OK;
5338 
5339 	if((template_names = (char *)strdup(this_contactgroup->template)) == NULL)
5340 		return ERROR;
5341 
5342 	/* apply all templates */
5343 	template_name_ptr = template_names;
5344 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
5345 
5346 		template_contactgroup = xodtemplate_find_contactgroup(temp_ptr);
5347 		if(template_contactgroup == NULL) {
5348 			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);
5349 			my_free(template_names);
5350 			return ERROR;
5351 			}
5352 
5353 		/* resolve the template contactgroup... */
5354 		xodtemplate_resolve_contactgroup(template_contactgroup);
5355 
5356 		/* apply missing properties from template contactgroup... */
5357 		xod_inherit_str_nohave(this_contactgroup, template_contactgroup, contactgroup_name);
5358 		xod_inherit_str_nohave(this_contactgroup, template_contactgroup, alias);
5359 
5360 		xodtemplate_get_inherited_string(&template_contactgroup->have_members, &template_contactgroup->members, &this_contactgroup->have_members, &this_contactgroup->members);
5361 		xodtemplate_get_inherited_string(&template_contactgroup->have_contactgroup_members, &template_contactgroup->contactgroup_members, &this_contactgroup->have_contactgroup_members, &this_contactgroup->contactgroup_members);
5362 
5363 		}
5364 
5365 	my_free(template_names);
5366 
5367 	return OK;
5368 	}
5369 
5370 
5371 
5372 
5373 /* resolves a hostgroup object */
xodtemplate_resolve_hostgroup(xodtemplate_hostgroup * this_hostgroup)5374 int xodtemplate_resolve_hostgroup(xodtemplate_hostgroup *this_hostgroup) {
5375 	char *temp_ptr = NULL;
5376 	char *template_names = NULL;
5377 	char *template_name_ptr = NULL;
5378 	xodtemplate_hostgroup *template_hostgroup = NULL;
5379 
5380 	/* return if this hostgroup has already been resolved */
5381 	if(this_hostgroup->has_been_resolved == TRUE)
5382 		return OK;
5383 
5384 	/* set the resolved flag */
5385 	this_hostgroup->has_been_resolved = TRUE;
5386 
5387 	/* return if we have no template */
5388 	if(this_hostgroup->template == NULL)
5389 		return OK;
5390 
5391 	if((template_names = (char *)strdup(this_hostgroup->template)) == NULL)
5392 		return ERROR;
5393 
5394 	/* apply all templates */
5395 	template_name_ptr = template_names;
5396 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
5397 
5398 		template_hostgroup = xodtemplate_find_hostgroup(temp_ptr);
5399 		if(template_hostgroup == NULL) {
5400 			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);
5401 			my_free(template_names);
5402 			return ERROR;
5403 			}
5404 
5405 		/* resolve the template hostgroup... */
5406 		xodtemplate_resolve_hostgroup(template_hostgroup);
5407 
5408 		/* apply missing properties from template hostgroup... */
5409 		xod_inherit_str_nohave(this_hostgroup, template_hostgroup, hostgroup_name);
5410 		xod_inherit_str_nohave(this_hostgroup, template_hostgroup, alias);
5411 
5412 		xodtemplate_get_inherited_string(&template_hostgroup->have_members, &template_hostgroup->members, &this_hostgroup->have_members, &this_hostgroup->members);
5413 		xodtemplate_get_inherited_string(&template_hostgroup->have_hostgroup_members, &template_hostgroup->hostgroup_members, &this_hostgroup->have_hostgroup_members, &this_hostgroup->hostgroup_members);
5414 
5415 		xod_inherit_str(this_hostgroup, template_hostgroup, notes);
5416 		xod_inherit_str(this_hostgroup, template_hostgroup, notes_url);
5417 		xod_inherit_str(this_hostgroup, template_hostgroup, action_url);
5418 		}
5419 
5420 	my_free(template_names);
5421 
5422 	return OK;
5423 	}
5424 
5425 
5426 
5427 
5428 /* resolves a servicegroup object */
xodtemplate_resolve_servicegroup(xodtemplate_servicegroup * this_servicegroup)5429 int xodtemplate_resolve_servicegroup(xodtemplate_servicegroup *this_servicegroup) {
5430 	char *temp_ptr = NULL;
5431 	char *template_names = NULL;
5432 	char *template_name_ptr = NULL;
5433 	xodtemplate_servicegroup *template_servicegroup = NULL;
5434 
5435 	/* return if this servicegroup has already been resolved */
5436 	if(this_servicegroup->has_been_resolved == TRUE)
5437 		return OK;
5438 
5439 	/* set the resolved flag */
5440 	this_servicegroup->has_been_resolved = TRUE;
5441 
5442 	/* return if we have no template */
5443 	if(this_servicegroup->template == NULL)
5444 		return OK;
5445 
5446 	if((template_names = (char *)strdup(this_servicegroup->template)) == NULL)
5447 		return ERROR;
5448 
5449 	/* apply all templates */
5450 	template_name_ptr = template_names;
5451 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
5452 
5453 		template_servicegroup = xodtemplate_find_servicegroup(temp_ptr);
5454 		if(template_servicegroup == NULL) {
5455 			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);
5456 			my_free(template_names);
5457 			return ERROR;
5458 			}
5459 
5460 		/* resolve the template servicegroup... */
5461 		xodtemplate_resolve_servicegroup(template_servicegroup);
5462 
5463 		/* apply missing properties from template servicegroup... */
5464 		xod_inherit_str_nohave(this_servicegroup, template_servicegroup, servicegroup_name);
5465 		xod_inherit_str_nohave(this_servicegroup, template_servicegroup, alias);
5466 
5467 		xodtemplate_get_inherited_string(&template_servicegroup->have_members, &template_servicegroup->members, &this_servicegroup->have_members, &this_servicegroup->members);
5468 		xodtemplate_get_inherited_string(&template_servicegroup->have_servicegroup_members, &template_servicegroup->servicegroup_members, &this_servicegroup->have_servicegroup_members, &this_servicegroup->servicegroup_members);
5469 
5470 		xod_inherit_str(this_servicegroup, template_servicegroup, notes);
5471 		xod_inherit_str(this_servicegroup, template_servicegroup, notes_url);
5472 		xod_inherit_str(this_servicegroup, template_servicegroup, action_url);
5473 		}
5474 
5475 	my_free(template_names);
5476 
5477 	return OK;
5478 	}
5479 
5480 
5481 /* resolves a servicedependency object */
xodtemplate_resolve_servicedependency(xodtemplate_servicedependency * this_servicedependency)5482 int xodtemplate_resolve_servicedependency(xodtemplate_servicedependency *this_servicedependency) {
5483 	char *temp_ptr = NULL;
5484 	char *template_names = NULL;
5485 	char *template_name_ptr = NULL;
5486 	xodtemplate_servicedependency *template_servicedependency = NULL;
5487 
5488 	/* return if this servicedependency has already been resolved */
5489 	if(this_servicedependency->has_been_resolved == TRUE)
5490 		return OK;
5491 
5492 	/* set the resolved flag */
5493 	this_servicedependency->has_been_resolved = TRUE;
5494 
5495 	/* return if we have no template */
5496 	if(this_servicedependency->template == NULL)
5497 		return OK;
5498 
5499 	if((template_names = (char *)strdup(this_servicedependency->template)) == NULL)
5500 		return ERROR;
5501 
5502 	/* apply all templates */
5503 	template_name_ptr = template_names;
5504 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
5505 
5506 		template_servicedependency = xodtemplate_find_servicedependency(temp_ptr);
5507 		if(template_servicedependency == NULL) {
5508 			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);
5509 			my_free(template_names);
5510 			return ERROR;
5511 			}
5512 
5513 		/* resolve the template servicedependency... */
5514 		xodtemplate_resolve_servicedependency(template_servicedependency);
5515 
5516 		/* apply missing properties from template servicedependency... */
5517 		xodtemplate_get_inherited_string(&template_servicedependency->have_servicegroup_name, &template_servicedependency->servicegroup_name, &this_servicedependency->have_servicegroup_name, &this_servicedependency->servicegroup_name);
5518 		xodtemplate_get_inherited_string(&template_servicedependency->have_hostgroup_name, &template_servicedependency->hostgroup_name, &this_servicedependency->have_hostgroup_name, &this_servicedependency->hostgroup_name);
5519 		xodtemplate_get_inherited_string(&template_servicedependency->have_host_name, &template_servicedependency->host_name, &this_servicedependency->have_host_name, &this_servicedependency->host_name);
5520 		xodtemplate_get_inherited_string(&template_servicedependency->have_service_description, &template_servicedependency->service_description, &this_servicedependency->have_service_description, &this_servicedependency->service_description);
5521 		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);
5522 		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);
5523 		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);
5524 		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);
5525 
5526 		if(this_servicedependency->have_dependency_period == FALSE && template_servicedependency->have_dependency_period == TRUE) {
5527 			if(this_servicedependency->dependency_period == NULL && template_servicedependency->dependency_period != NULL)
5528 				this_servicedependency->dependency_period = (char *)strdup(template_servicedependency->dependency_period);
5529 			this_servicedependency->have_dependency_period = TRUE;
5530 			}
5531 		if(this_servicedependency->have_inherits_parent == FALSE && template_servicedependency->have_inherits_parent == TRUE) {
5532 			this_servicedependency->inherits_parent = template_servicedependency->inherits_parent;
5533 			this_servicedependency->have_inherits_parent = TRUE;
5534 			}
5535 		if(this_servicedependency->have_execution_failure_options == FALSE && template_servicedependency->have_execution_failure_options == TRUE) {
5536 			this_servicedependency->execution_failure_options = template_servicedependency->execution_failure_options;
5537 			this_servicedependency->have_execution_failure_options = TRUE;
5538 			}
5539 		if(this_servicedependency->have_notification_failure_options == FALSE && template_servicedependency->have_notification_failure_options == TRUE) {
5540 			this_servicedependency->notification_failure_options = template_servicedependency->notification_failure_options;
5541 			this_servicedependency->have_notification_failure_options = TRUE;
5542 			}
5543 		}
5544 
5545 	my_free(template_names);
5546 
5547 	return OK;
5548 	}
5549 
5550 
5551 /* resolves a serviceescalation object */
xodtemplate_resolve_serviceescalation(xodtemplate_serviceescalation * this_serviceescalation)5552 int xodtemplate_resolve_serviceescalation(xodtemplate_serviceescalation *this_serviceescalation) {
5553 	char *temp_ptr = NULL;
5554 	char *template_names = NULL;
5555 	char *template_name_ptr = NULL;
5556 	xodtemplate_serviceescalation *template_serviceescalation = NULL;
5557 
5558 	/* return if this serviceescalation has already been resolved */
5559 	if(this_serviceescalation->has_been_resolved == TRUE)
5560 		return OK;
5561 
5562 	/* set the resolved flag */
5563 	this_serviceescalation->has_been_resolved = TRUE;
5564 
5565 	/* return if we have no template */
5566 	if(this_serviceescalation->template == NULL)
5567 		return OK;
5568 
5569 	if((template_names = (char *)strdup(this_serviceescalation->template)) == NULL)
5570 		return ERROR;
5571 
5572 	/* apply all templates */
5573 	template_name_ptr = template_names;
5574 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
5575 
5576 		template_serviceescalation = xodtemplate_find_serviceescalation(temp_ptr);
5577 		if(template_serviceescalation == NULL) {
5578 			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);
5579 			my_free(template_names);
5580 			return ERROR;
5581 			}
5582 
5583 		/* resolve the template serviceescalation... */
5584 		xodtemplate_resolve_serviceescalation(template_serviceescalation);
5585 
5586 		/* apply missing properties from template serviceescalation... */
5587 		xodtemplate_get_inherited_string(&template_serviceescalation->have_servicegroup_name, &template_serviceescalation->servicegroup_name, &this_serviceescalation->have_servicegroup_name, &this_serviceescalation->servicegroup_name);
5588 		xodtemplate_get_inherited_string(&template_serviceescalation->have_hostgroup_name, &template_serviceescalation->hostgroup_name, &this_serviceescalation->have_hostgroup_name, &this_serviceescalation->hostgroup_name);
5589 		xodtemplate_get_inherited_string(&template_serviceescalation->have_host_name, &template_serviceescalation->host_name, &this_serviceescalation->have_host_name, &this_serviceescalation->host_name);
5590 		xodtemplate_get_inherited_string(&template_serviceescalation->have_service_description, &template_serviceescalation->service_description, &this_serviceescalation->have_service_description, &this_serviceescalation->service_description);
5591 		xodtemplate_get_inherited_string(&template_serviceescalation->have_contact_groups, &template_serviceescalation->contact_groups, &this_serviceescalation->have_contact_groups, &this_serviceescalation->contact_groups);
5592 		xodtemplate_get_inherited_string(&template_serviceescalation->have_contacts, &template_serviceescalation->contacts, &this_serviceescalation->have_contacts, &this_serviceescalation->contacts);
5593 
5594 		if(this_serviceescalation->have_escalation_period == FALSE && template_serviceescalation->have_escalation_period == TRUE) {
5595 			if(this_serviceescalation->escalation_period == NULL && template_serviceescalation->escalation_period != NULL)
5596 				this_serviceescalation->escalation_period = (char *)strdup(template_serviceescalation->escalation_period);
5597 			this_serviceescalation->have_escalation_period = TRUE;
5598 			}
5599 		if(this_serviceescalation->have_first_notification == FALSE && template_serviceescalation->have_first_notification == TRUE) {
5600 			this_serviceescalation->first_notification = template_serviceescalation->first_notification;
5601 			this_serviceescalation->have_first_notification = TRUE;
5602 			}
5603 		if(this_serviceescalation->have_last_notification == FALSE && template_serviceescalation->have_last_notification == TRUE) {
5604 			this_serviceescalation->last_notification = template_serviceescalation->last_notification;
5605 			this_serviceescalation->have_last_notification = TRUE;
5606 			}
5607 		if(this_serviceescalation->have_notification_interval == FALSE && template_serviceescalation->have_notification_interval == TRUE) {
5608 			this_serviceescalation->notification_interval = template_serviceescalation->notification_interval;
5609 			this_serviceescalation->have_notification_interval = TRUE;
5610 			}
5611 		if(this_serviceescalation->have_escalation_options == FALSE && template_serviceescalation->have_escalation_options == TRUE) {
5612 			this_serviceescalation->escalation_options = template_serviceescalation->escalation_options;
5613 			this_serviceescalation->have_escalation_options = TRUE;
5614 			}
5615 		}
5616 
5617 	my_free(template_names);
5618 
5619 	return OK;
5620 	}
5621 
5622 
5623 
5624 /* resolves a contact object */
xodtemplate_resolve_contact(xodtemplate_contact * this_contact)5625 int xodtemplate_resolve_contact(xodtemplate_contact *this_contact) {
5626 	char *temp_ptr = NULL;
5627 	char *template_names = NULL;
5628 	char *template_name_ptr = NULL;
5629 	xodtemplate_contact *template_contact = NULL;
5630 	xodtemplate_customvariablesmember *this_customvariablesmember = NULL;
5631 	xodtemplate_customvariablesmember *temp_customvariablesmember = NULL;
5632 	int x;
5633 
5634 	/* return if this contact has already been resolved */
5635 	if(this_contact->has_been_resolved == TRUE)
5636 		return OK;
5637 
5638 	/* set the resolved flag */
5639 	this_contact->has_been_resolved = TRUE;
5640 
5641 	/* return if we have no template */
5642 	if(this_contact->template == NULL)
5643 		return OK;
5644 
5645 	if((template_names = (char *)strdup(this_contact->template)) == NULL)
5646 		return ERROR;
5647 
5648 	/* apply all templates */
5649 	template_name_ptr = template_names;
5650 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
5651 
5652 		template_contact = xodtemplate_find_contact(temp_ptr);
5653 		if(template_contact == NULL) {
5654 			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);
5655 			my_free(template_names);
5656 			return ERROR;
5657 			}
5658 
5659 		/* resolve the template contact... */
5660 		xodtemplate_resolve_contact(template_contact);
5661 
5662 		/* apply missing properties from template contact... */
5663 		xod_inherit_str_nohave(this_contact, template_contact, contact_name);
5664 		xod_inherit_str_nohave(this_contact, template_contact, alias);
5665 
5666 		xod_inherit_str(this_contact, template_contact, email);
5667 		xod_inherit_str(this_contact, template_contact, pager);
5668 		for(x = 0; x < MAX_XODTEMPLATE_CONTACT_ADDRESSES; x++)
5669 			xod_inherit_str(this_contact, template_contact, address[x]);
5670 
5671 		xodtemplate_get_inherited_string(&template_contact->have_contact_groups, &template_contact->contact_groups, &this_contact->have_contact_groups, &this_contact->contact_groups);
5672 		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);
5673 		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);
5674 
5675 		xod_inherit_str(this_contact, template_contact, host_notification_period);
5676 		xod_inherit_str(this_contact, template_contact, service_notification_period);
5677 		xod_inherit(this_contact, template_contact, host_notification_options);
5678 		xod_inherit(this_contact, template_contact, service_notification_options);
5679 		xod_inherit(this_contact, template_contact, host_notifications_enabled);
5680 		xod_inherit(this_contact, template_contact, service_notifications_enabled);
5681 		xod_inherit(this_contact, template_contact, can_submit_commands);
5682 		xod_inherit(this_contact, template_contact, retain_status_information);
5683 		xod_inherit(this_contact, template_contact, retain_nonstatus_information);
5684 		xod_inherit(this_contact, template_contact, minimum_value);
5685 
5686 		/* apply missing custom variables from template contact... */
5687 		for(temp_customvariablesmember = template_contact->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) {
5688 
5689 			/* see if this host has a variable by the same name */
5690 			for(this_customvariablesmember = this_contact->custom_variables; this_customvariablesmember != NULL; this_customvariablesmember = this_customvariablesmember->next) {
5691 				if(!strcmp(temp_customvariablesmember->variable_name, this_customvariablesmember->variable_name))
5692 					break;
5693 				}
5694 
5695 			/* we didn't find the same variable name, so add a new custom variable */
5696 			if(this_customvariablesmember == NULL)
5697 				xodtemplate_add_custom_variable_to_contact(this_contact, temp_customvariablesmember->variable_name, temp_customvariablesmember->variable_value);
5698 			}
5699 		}
5700 
5701 	my_free(template_names);
5702 
5703 	return OK;
5704 	}
5705 
5706 
5707 
5708 /* resolves a host object */
xodtemplate_resolve_host(xodtemplate_host * this_host)5709 int xodtemplate_resolve_host(xodtemplate_host *this_host) {
5710 	char *temp_ptr = NULL;
5711 	char *template_names = NULL;
5712 	char *template_name_ptr = NULL;
5713 	xodtemplate_host *template_host = NULL;
5714 	xodtemplate_customvariablesmember *this_customvariablesmember = NULL;
5715 	xodtemplate_customvariablesmember *temp_customvariablesmember = NULL;
5716 
5717 	/* return if this host has already been resolved */
5718 	if(this_host->has_been_resolved == TRUE)
5719 		return OK;
5720 
5721 	/* set the resolved flag */
5722 	this_host->has_been_resolved = TRUE;
5723 
5724 	/* return if we have no template */
5725 	if(this_host->template == NULL)
5726 		return OK;
5727 
5728 	if((template_names = (char *)strdup(this_host->template)) == NULL)
5729 		return ERROR;
5730 
5731 	/* apply all templates */
5732 	template_name_ptr = template_names;
5733 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
5734 
5735 		template_host = xodtemplate_find_host(temp_ptr);
5736 		if(template_host == NULL) {
5737 			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);
5738 			my_free(template_names);
5739 			return ERROR;
5740 			}
5741 
5742 		/* resolve the template host... */
5743 		xodtemplate_resolve_host(template_host);
5744 
5745 		/* apply missing properties from template host... */
5746 		xod_inherit_str_nohave(this_host, template_host, host_name);
5747 		xod_inherit_str(this_host, template_host, display_name);
5748 		xod_inherit_str_nohave(this_host, template_host, alias);
5749 		xod_inherit_str_nohave(this_host, template_host, address);
5750 
5751 		xodtemplate_get_inherited_string(&template_host->have_parents, &template_host->parents, &this_host->have_parents, &this_host->parents);
5752 		xodtemplate_get_inherited_string(&template_host->have_host_groups, &template_host->host_groups, &this_host->have_host_groups, &this_host->host_groups);
5753 		xodtemplate_get_inherited_string(&template_host->have_contact_groups, &template_host->contact_groups, &this_host->have_contact_groups, &this_host->contact_groups);
5754 		xodtemplate_get_inherited_string(&template_host->have_contacts, &template_host->contacts, &this_host->have_contacts, &this_host->contacts);
5755 
5756 
5757 		xod_inherit_str(this_host, template_host, check_command);
5758 		xod_inherit_str(this_host, template_host, check_period);
5759 		xod_inherit_str(this_host, template_host, event_handler);
5760 		xod_inherit_str(this_host, template_host, notification_period);
5761 		xod_inherit_str(this_host, template_host, notes);
5762 		xod_inherit_str(this_host, template_host, notes_url);
5763 		xod_inherit_str(this_host, template_host, action_url);
5764 		xod_inherit_str(this_host, template_host, icon_image);
5765 		xod_inherit_str(this_host, template_host, icon_image_alt);
5766 		xod_inherit_str(this_host, template_host, vrml_image);
5767 		xod_inherit_str(this_host, template_host, statusmap_image);
5768 
5769 		xod_inherit(this_host, template_host, initial_state);
5770 		xod_inherit(this_host, template_host, check_interval);
5771 		xod_inherit(this_host, template_host, retry_interval);
5772 		xod_inherit(this_host, template_host, max_check_attempts);
5773 		xod_inherit(this_host, template_host, active_checks_enabled);
5774 		xod_inherit(this_host, template_host, passive_checks_enabled);
5775 		xod_inherit(this_host, template_host, obsess);
5776 		xod_inherit(this_host, template_host, event_handler_enabled);
5777 		xod_inherit(this_host, template_host, check_freshness);
5778 		xod_inherit(this_host, template_host, freshness_threshold);
5779 		xod_inherit(this_host, template_host, low_flap_threshold);
5780 		xod_inherit(this_host, template_host, high_flap_threshold);
5781 		xod_inherit(this_host, template_host, flap_detection_enabled);
5782 		xod_inherit(this_host, template_host, flap_detection_options);
5783 		xod_inherit(this_host, template_host, notification_options);
5784 		xod_inherit(this_host, template_host, notifications_enabled);
5785 		xod_inherit(this_host, template_host, notification_interval);
5786 		xod_inherit(this_host, template_host, first_notification_delay);
5787 		xod_inherit(this_host, template_host, stalking_options);
5788 		xod_inherit(this_host, template_host, process_perf_data);
5789 		xod_inherit(this_host, template_host, hourly_value);
5790 
5791 		if(this_host->have_2d_coords == FALSE && template_host->have_2d_coords == TRUE) {
5792 			this_host->x_2d = template_host->x_2d;
5793 			this_host->y_2d = template_host->y_2d;
5794 			this_host->have_2d_coords = TRUE;
5795 			}
5796 		if(this_host->have_3d_coords == FALSE && template_host->have_3d_coords == TRUE) {
5797 			this_host->x_3d = template_host->x_3d;
5798 			this_host->y_3d = template_host->y_3d;
5799 			this_host->z_3d = template_host->z_3d;
5800 			this_host->have_3d_coords = TRUE;
5801 			}
5802 
5803 		xod_inherit(this_host, template_host, retain_status_information);
5804 		xod_inherit(this_host, template_host, retain_nonstatus_information);
5805 
5806 		/* apply missing custom variables from template host... */
5807 		for(temp_customvariablesmember = template_host->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) {
5808 
5809 			/* see if this host has a variable by the same name */
5810 			for(this_customvariablesmember = this_host->custom_variables; this_customvariablesmember != NULL; this_customvariablesmember = this_customvariablesmember->next) {
5811 				if(!strcmp(temp_customvariablesmember->variable_name, this_customvariablesmember->variable_name))
5812 					break;
5813 				}
5814 
5815 			/* we didn't find the same variable name, so add a new custom variable */
5816 			if(this_customvariablesmember == NULL)
5817 				xodtemplate_add_custom_variable_to_host(this_host, temp_customvariablesmember->variable_name, temp_customvariablesmember->variable_value);
5818 			}
5819 		}
5820 
5821 	my_free(template_names);
5822 
5823 	return OK;
5824 	}
5825 
5826 
5827 
5828 /* resolves a service object */
xodtemplate_resolve_service(xodtemplate_service * this_service)5829 int xodtemplate_resolve_service(xodtemplate_service *this_service) {
5830 	char *temp_ptr = NULL;
5831 	char *template_names = NULL;
5832 	char *template_name_ptr = NULL;
5833 	xodtemplate_service *template_service = NULL;
5834 	xodtemplate_customvariablesmember *this_customvariablesmember = NULL;
5835 	xodtemplate_customvariablesmember *temp_customvariablesmember = NULL;
5836 
5837 	/* return if this service has already been resolved */
5838 	if(this_service->has_been_resolved == TRUE)
5839 		return OK;
5840 
5841 	/* set the resolved flag */
5842 	this_service->has_been_resolved = TRUE;
5843 
5844 	/* return if we have no template */
5845 	if(this_service->template == NULL)
5846 		return OK;
5847 
5848 	if((template_names = (char *)strdup(this_service->template)) == NULL)
5849 		return ERROR;
5850 
5851 	/* apply all templates */
5852 	template_name_ptr = template_names;
5853 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
5854 
5855 		template_service = xodtemplate_find_service(temp_ptr);
5856 		if(template_service == NULL) {
5857 			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);
5858 			my_free(template_names);
5859 			return ERROR;
5860 			}
5861 
5862 		/* resolve the template service... */
5863 		xodtemplate_resolve_service(template_service);
5864 
5865 		/* apply missing properties from template service... */
5866 		xod_inherit_str(this_service, template_service, service_description);
5867 		xod_inherit_str(this_service, template_service, display_name);
5868 
5869 		xodtemplate_get_inherited_string(&template_service->have_parents, &template_service->parents, &this_service->have_parents, &this_service->parents);
5870 		xodtemplate_get_inherited_string(&template_service->have_host_name, &template_service->host_name, &this_service->have_host_name, &this_service->host_name);
5871 		xodtemplate_get_inherited_string(&template_service->have_hostgroup_name, &template_service->hostgroup_name, &this_service->have_hostgroup_name, &this_service->hostgroup_name);
5872 		xodtemplate_get_inherited_string(&template_service->have_service_groups, &template_service->service_groups, &this_service->have_service_groups, &this_service->service_groups);
5873 		xodtemplate_get_inherited_string(&template_service->have_contact_groups, &template_service->contact_groups, &this_service->have_contact_groups, &this_service->contact_groups);
5874 		xodtemplate_get_inherited_string(&template_service->have_contacts, &template_service->contacts, &this_service->have_contacts, &this_service->contacts);
5875 
5876 		if(template_service->have_check_command == TRUE) {
5877 			if(template_service->have_important_check_command == TRUE) {
5878 				my_free(this_service->check_command);
5879 				this_service->have_check_command = FALSE;
5880 				}
5881 			}
5882 		xod_inherit_str(this_service, template_service, check_command);
5883 
5884 		xod_inherit_str(this_service, template_service, check_period);
5885 		xod_inherit_str(this_service, template_service, event_handler);
5886 		xod_inherit_str(this_service, template_service, notification_period);
5887 		xod_inherit_str(this_service, template_service, notes);
5888 		xod_inherit_str(this_service, template_service, notes_url);
5889 		xod_inherit_str(this_service, template_service, action_url);
5890 		xod_inherit_str(this_service, template_service, icon_image);
5891 		xod_inherit_str(this_service, template_service, icon_image_alt);
5892 
5893 		xod_inherit(this_service, template_service, initial_state);
5894 		xod_inherit(this_service, template_service, max_check_attempts);
5895 		xod_inherit(this_service, template_service, check_interval);
5896 		xod_inherit(this_service, template_service, retry_interval);
5897 		xod_inherit(this_service, template_service, active_checks_enabled);
5898 		xod_inherit(this_service, template_service, passive_checks_enabled);
5899 		xod_inherit(this_service, template_service, parallelize_check);
5900 		xod_inherit(this_service, template_service, is_volatile);
5901 		xod_inherit(this_service, template_service, obsess);
5902 		xod_inherit(this_service, template_service, event_handler_enabled);
5903 		xod_inherit(this_service, template_service, check_freshness);
5904 		xod_inherit(this_service, template_service, freshness_threshold);
5905 		xod_inherit(this_service, template_service, low_flap_threshold);
5906 		xod_inherit(this_service, template_service, high_flap_threshold);
5907 		xod_inherit(this_service, template_service, flap_detection_enabled);
5908 		xod_inherit(this_service, template_service, flap_detection_options);
5909 		xod_inherit(this_service, template_service, notification_options);
5910 		xod_inherit(this_service, template_service, notifications_enabled);
5911 		xod_inherit(this_service, template_service, notification_interval);
5912 		xod_inherit(this_service, template_service, first_notification_delay);
5913 		xod_inherit(this_service, template_service, stalking_options);
5914 		xod_inherit(this_service, template_service, process_perf_data);
5915 		xod_inherit(this_service, template_service, retain_status_information);
5916 		xod_inherit(this_service, template_service, retain_nonstatus_information);
5917 		xod_inherit(this_service, template_service, hourly_value);
5918 
5919 		/* apply missing custom variables from template service... */
5920 		for(temp_customvariablesmember = template_service->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) {
5921 
5922 			/* see if this host has a variable by the same name */
5923 			for(this_customvariablesmember = this_service->custom_variables; this_customvariablesmember != NULL; this_customvariablesmember = this_customvariablesmember->next) {
5924 				if(!strcmp(temp_customvariablesmember->variable_name, this_customvariablesmember->variable_name))
5925 					break;
5926 				}
5927 
5928 			/* we didn't find the same variable name, so add a new custom variable */
5929 			if(this_customvariablesmember == NULL)
5930 				xodtemplate_add_custom_variable_to_service(this_service, temp_customvariablesmember->variable_name, temp_customvariablesmember->variable_value);
5931 			}
5932 		}
5933 
5934 	my_free(template_names);
5935 
5936 	return OK;
5937 	}
5938 
5939 
5940 /* resolves a hostdependency object */
xodtemplate_resolve_hostdependency(xodtemplate_hostdependency * this_hostdependency)5941 int xodtemplate_resolve_hostdependency(xodtemplate_hostdependency *this_hostdependency) {
5942 	char *temp_ptr = NULL;
5943 	char *template_names = NULL;
5944 	char *template_name_ptr = NULL;
5945 	xodtemplate_hostdependency *template_hostdependency = NULL;
5946 
5947 	/* return if this hostdependency has already been resolved */
5948 	if(this_hostdependency->has_been_resolved == TRUE)
5949 		return OK;
5950 
5951 	/* set the resolved flag */
5952 	this_hostdependency->has_been_resolved = TRUE;
5953 
5954 	/* return if we have no template */
5955 	if(this_hostdependency->template == NULL)
5956 		return OK;
5957 
5958 	if((template_names = (char *)strdup(this_hostdependency->template)) == NULL)
5959 		return ERROR;
5960 
5961 	/* apply all templates */
5962 	template_name_ptr = template_names;
5963 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
5964 
5965 		template_hostdependency = xodtemplate_find_hostdependency(temp_ptr);
5966 		if(template_hostdependency == NULL) {
5967 			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);
5968 			my_free(template_names);
5969 			return ERROR;
5970 			}
5971 
5972 		/* resolve the template hostdependency... */
5973 		xodtemplate_resolve_hostdependency(template_hostdependency);
5974 
5975 		/* apply missing properties from template hostdependency... */
5976 
5977 		xodtemplate_get_inherited_string(&template_hostdependency->have_host_name, &template_hostdependency->host_name, &this_hostdependency->have_host_name, &this_hostdependency->host_name);
5978 		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);
5979 		xodtemplate_get_inherited_string(&template_hostdependency->have_hostgroup_name, &template_hostdependency->hostgroup_name, &this_hostdependency->have_hostgroup_name, &this_hostdependency->hostgroup_name);
5980 		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);
5981 
5982 		xod_inherit_str(this_hostdependency, template_hostdependency, dependency_period);
5983 		xod_inherit(this_hostdependency, template_hostdependency, inherits_parent);
5984 		xod_inherit(this_hostdependency, template_hostdependency, execution_failure_options);
5985 		xod_inherit(this_hostdependency, template_hostdependency, notification_failure_options);
5986 		}
5987 
5988 	my_free(template_names);
5989 
5990 	return OK;
5991 	}
5992 
5993 
5994 /* resolves a hostescalation object */
xodtemplate_resolve_hostescalation(xodtemplate_hostescalation * this_hostescalation)5995 int xodtemplate_resolve_hostescalation(xodtemplate_hostescalation *this_hostescalation) {
5996 	char *temp_ptr = NULL;
5997 	char *template_names = NULL;
5998 	char *template_name_ptr = NULL;
5999 	xodtemplate_hostescalation *template_hostescalation = NULL;
6000 
6001 	/* return if this hostescalation has already been resolved */
6002 	if(this_hostescalation->has_been_resolved == TRUE)
6003 		return OK;
6004 
6005 	/* set the resolved flag */
6006 	this_hostescalation->has_been_resolved = TRUE;
6007 
6008 	/* return if we have no template */
6009 	if(this_hostescalation->template == NULL)
6010 		return OK;
6011 
6012 	if((template_names = (char *)strdup(this_hostescalation->template)) == NULL)
6013 		return ERROR;
6014 
6015 	/* apply all templates */
6016 	template_name_ptr = template_names;
6017 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
6018 
6019 		template_hostescalation = xodtemplate_find_hostescalation(temp_ptr);
6020 		if(template_hostescalation == NULL) {
6021 			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);
6022 			my_free(template_names);
6023 			return ERROR;
6024 			}
6025 
6026 		/* resolve the template hostescalation... */
6027 		xodtemplate_resolve_hostescalation(template_hostescalation);
6028 
6029 		/* apply missing properties from template hostescalation... */
6030 		xodtemplate_get_inherited_string(&template_hostescalation->have_host_name, &template_hostescalation->host_name, &this_hostescalation->have_host_name, &this_hostescalation->host_name);
6031 		xodtemplate_get_inherited_string(&template_hostescalation->have_hostgroup_name, &template_hostescalation->hostgroup_name, &this_hostescalation->have_hostgroup_name, &this_hostescalation->hostgroup_name);
6032 		xodtemplate_get_inherited_string(&template_hostescalation->have_contact_groups, &template_hostescalation->contact_groups, &this_hostescalation->have_contact_groups, &this_hostescalation->contact_groups);
6033 		xodtemplate_get_inherited_string(&template_hostescalation->have_contacts, &template_hostescalation->contacts, &this_hostescalation->have_contacts, &this_hostescalation->contacts);
6034 
6035 		xod_inherit_str(this_hostescalation, template_hostescalation, escalation_period);
6036 		xod_inherit(this_hostescalation, template_hostescalation, first_notification);
6037 		xod_inherit(this_hostescalation, template_hostescalation, last_notification);
6038 		xod_inherit(this_hostescalation, template_hostescalation, notification_interval);
6039 		xod_inherit(this_hostescalation, template_hostescalation, escalation_options);
6040 		}
6041 
6042 	my_free(template_names);
6043 
6044 	return OK;
6045 	}
6046 
6047 
6048 
6049 /* resolves a hostextinfo object */
xodtemplate_resolve_hostextinfo(xodtemplate_hostextinfo * this_hostextinfo)6050 int xodtemplate_resolve_hostextinfo(xodtemplate_hostextinfo *this_hostextinfo) {
6051 	char *temp_ptr = NULL;
6052 	char *template_names = NULL;
6053 	char *template_name_ptr = NULL;
6054 	xodtemplate_hostextinfo *template_hostextinfo = NULL;
6055 
6056 	/* return if this object has already been resolved */
6057 	if(this_hostextinfo->has_been_resolved == TRUE)
6058 		return OK;
6059 
6060 	/* set the resolved flag */
6061 	this_hostextinfo->has_been_resolved = TRUE;
6062 
6063 	/* return if we have no template */
6064 	if(this_hostextinfo->template == NULL)
6065 		return OK;
6066 
6067 	if((template_names = (char *)strdup(this_hostextinfo->template)) == NULL)
6068 		return ERROR;
6069 
6070 	/* apply all templates */
6071 	template_name_ptr = template_names;
6072 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
6073 
6074 		template_hostextinfo = xodtemplate_find_hostextinfo(temp_ptr);
6075 		if(template_hostextinfo == NULL) {
6076 			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);
6077 			my_free(template_names);
6078 			return ERROR;
6079 			}
6080 
6081 		/* resolve the template hostextinfo... */
6082 		xodtemplate_resolve_hostextinfo(template_hostextinfo);
6083 
6084 		/* apply missing properties from template hostextinfo... */
6085 		xod_inherit_str(this_hostextinfo, template_hostextinfo, host_name);
6086 		xod_inherit_str(this_hostextinfo, template_hostextinfo, hostgroup_name);
6087 		xod_inherit_str(this_hostextinfo, template_hostextinfo, notes);
6088 		xod_inherit_str(this_hostextinfo, template_hostextinfo, notes_url);
6089 		xod_inherit_str(this_hostextinfo, template_hostextinfo, action_url);
6090 		xod_inherit_str(this_hostextinfo, template_hostextinfo, icon_image);
6091 		xod_inherit_str(this_hostextinfo, template_hostextinfo, icon_image_alt);
6092 		xod_inherit_str(this_hostextinfo, template_hostextinfo, vrml_image);
6093 		xod_inherit_str(this_hostextinfo, template_hostextinfo, statusmap_image);
6094 
6095 		if(this_hostextinfo->have_2d_coords == FALSE && template_hostextinfo->have_2d_coords == TRUE) {
6096 			this_hostextinfo->x_2d = template_hostextinfo->x_2d;
6097 			this_hostextinfo->y_2d = template_hostextinfo->y_2d;
6098 			this_hostextinfo->have_2d_coords = TRUE;
6099 			}
6100 		if(this_hostextinfo->have_3d_coords == FALSE && template_hostextinfo->have_3d_coords == TRUE) {
6101 			this_hostextinfo->x_3d = template_hostextinfo->x_3d;
6102 			this_hostextinfo->y_3d = template_hostextinfo->y_3d;
6103 			this_hostextinfo->z_3d = template_hostextinfo->z_3d;
6104 			this_hostextinfo->have_3d_coords = TRUE;
6105 			}
6106 		}
6107 
6108 	my_free(template_names);
6109 
6110 	return OK;
6111 	}
6112 
6113 
6114 
6115 /* resolves a serviceextinfo object */
xodtemplate_resolve_serviceextinfo(xodtemplate_serviceextinfo * this_serviceextinfo)6116 int xodtemplate_resolve_serviceextinfo(xodtemplate_serviceextinfo *this_serviceextinfo) {
6117 	char *temp_ptr = NULL;
6118 	char *template_names = NULL;
6119 	char *template_name_ptr = NULL;
6120 	xodtemplate_serviceextinfo *template_serviceextinfo = NULL;
6121 
6122 	/* return if this object has already been resolved */
6123 	if(this_serviceextinfo->has_been_resolved == TRUE)
6124 		return OK;
6125 
6126 	/* set the resolved flag */
6127 	this_serviceextinfo->has_been_resolved = TRUE;
6128 
6129 	/* return if we have no template */
6130 	if(this_serviceextinfo->template == NULL)
6131 		return OK;
6132 
6133 	if((template_names = (char *)strdup(this_serviceextinfo->template)) == NULL)
6134 		return ERROR;
6135 
6136 	/* apply all templates */
6137 	template_name_ptr = template_names;
6138 	for(temp_ptr = my_strsep(&template_name_ptr, ","); temp_ptr != NULL; temp_ptr = my_strsep(&template_name_ptr, ",")) {
6139 
6140 		template_serviceextinfo = xodtemplate_find_serviceextinfo(temp_ptr);
6141 		if(template_serviceextinfo == NULL) {
6142 			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);
6143 			my_free(template_names);
6144 			return ERROR;
6145 			}
6146 
6147 		/* resolve the template serviceextinfo... */
6148 		xodtemplate_resolve_serviceextinfo(template_serviceextinfo);
6149 
6150 		/* apply missing properties from template serviceextinfo... */
6151 		xod_inherit_str(this_serviceextinfo, template_serviceextinfo, host_name);
6152 		xod_inherit_str(this_serviceextinfo, template_serviceextinfo, hostgroup_name);
6153 		xod_inherit_str(this_serviceextinfo, template_serviceextinfo, service_description);
6154 		xod_inherit_str(this_serviceextinfo, template_serviceextinfo, notes);
6155 		xod_inherit_str(this_serviceextinfo, template_serviceextinfo, notes_url);
6156 		xod_inherit_str(this_serviceextinfo, template_serviceextinfo, action_url);
6157 		xod_inherit_str(this_serviceextinfo, template_serviceextinfo, icon_image);
6158 		xod_inherit_str(this_serviceextinfo, template_serviceextinfo, icon_image_alt);
6159 		}
6160 
6161 	my_free(template_names);
6162 
6163 	return OK;
6164 	}
6165 
6166 
6167 
6168 #endif
6169 
6170 /******************************************************************/
6171 /*************** OBJECT RECOMBOBULATION FUNCTIONS *****************/
6172 /******************************************************************/
6173 
6174 /*
6175  * note: The cast to xodtemplate_host works for all objects because 'id'
6176  * is the first item of host, service and contact structs, and C
6177  * guarantees that the first member is always the same as the one listed
6178  * in the struct definition.
6179  */
_xodtemplate_add_group_member(objectlist ** list,bitmap * in,bitmap * reject,void * obj)6180 static int _xodtemplate_add_group_member(objectlist **list, bitmap *in, bitmap *reject, void *obj) {
6181 	xodtemplate_host *h = (xodtemplate_host *)obj;
6182 
6183 	if(!list || !obj)
6184 		return ERROR;
6185 
6186 	if(bitmap_isset(in, h->id) || bitmap_isset(reject, h->id))
6187 		return OK;
6188 	bitmap_set(in, h->id);
6189 	return prepend_object_to_objectlist(list, obj);
6190 	}
6191 #define xodtemplate_add_group_member(g, m) \
6192 	_xodtemplate_add_group_member(&g->member_list, g->member_map, g->reject_map, m)
6193 #define xodtemplate_add_servicegroup_member xodtemplate_add_group_member
6194 #define xodtemplate_add_contactgroup_member xodtemplate_add_group_member
6195 #define xodtemplate_add_hostgroup_member xodtemplate_add_group_member
6196 
6197 
6198 /* recombobulates contactgroup definitions */
xodtemplate_recombobulate_contactgroup_subgroups(xodtemplate_contactgroup * temp_contactgroup)6199 static int xodtemplate_recombobulate_contactgroup_subgroups(xodtemplate_contactgroup *temp_contactgroup) {
6200 	objectlist *mlist, *glist;
6201 
6202 	if(temp_contactgroup == NULL)
6203 		return ERROR;
6204 
6205 	/* if this one's already handled somehow, we return early */
6206 	if(temp_contactgroup->loop_status != XOD_NEW)
6207 		return temp_contactgroup->loop_status;
6208 
6209 	/* mark it as seen */
6210 	temp_contactgroup->loop_status = XOD_SEEN;
6211 
6212 	/* resolve included groups' members and add them to ours */
6213 	for(glist = temp_contactgroup->group_list; glist; glist = glist->next) {
6214 		int result;
6215 		xodtemplate_contactgroup *inc = (xodtemplate_contactgroup *)glist->object_ptr;
6216 		result = xodtemplate_recombobulate_contactgroup_subgroups(inc);
6217 		if(result != XOD_OK) {
6218 			if(result == ERROR)
6219 				return ERROR;
6220 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Contactgroups '%s' and '%s' are part of a contactgroup_members include loop\n", temp_contactgroup->contactgroup_name, inc->contactgroup_name);
6221 			inc->loop_status = XOD_LOOPY;
6222 			temp_contactgroup->loop_status = XOD_LOOPY;
6223 			break;
6224 			}
6225 
6226 		for(mlist = inc->member_list; mlist; mlist = mlist->next) {
6227 			xodtemplate_contact *c = (xodtemplate_contact *)mlist->object_ptr;
6228 			if(xodtemplate_add_contactgroup_member(temp_contactgroup, c) != OK) {
6229 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Failed to add '%s' as a subgroup member contact of contactgroup '%s' from contactgroup '%s'\n",
6230 					  c->contact_name, temp_contactgroup->contactgroup_name, inc->contactgroup_name);
6231 				return ERROR;
6232 				}
6233 			}
6234 		}
6235 
6236 	if(temp_contactgroup->loop_status == XOD_SEEN)
6237 		temp_contactgroup->loop_status = XOD_OK;
6238 
6239 	return temp_contactgroup->loop_status;
6240 	}
6241 
6242 
6243 
xodtemplate_recombobulate_contactgroups(void)6244 int xodtemplate_recombobulate_contactgroups(void) {
6245 	xodtemplate_contact *temp_contact = NULL;
6246 	xodtemplate_contactgroup *temp_contactgroup = NULL;
6247 	char *contactgroup_names = NULL;
6248 	char *temp_ptr = NULL;
6249 
6250 	/* 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 */
6251 	for(temp_contactgroup = xodtemplate_contactgroup_list; temp_contactgroup; temp_contactgroup = temp_contactgroup->next) {
6252 		objectlist *next, *list, *accept = NULL;
6253 
6254 		/*
6255 		 * If the contactgroup has no accept or reject list and no group
6256 		 * members we don't need the bitmaps for it. bitmap_isset()
6257 		 * will return 0 when passed a NULL map, so we can safely use
6258 		 * that to add any items from the object list later
6259 		 */
6260 		if(temp_contactgroup->members == NULL && temp_contactgroup->contactgroup_members == NULL)
6261 			continue;
6262 
6263 		if(!(temp_contactgroup->member_map = bitmap_create(xodcount.contacts))) {
6264 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not create contactgroup bitmap\n");
6265 			return ERROR;
6266 			}
6267 
6268 		if(temp_contactgroup->contactgroup_members) {
6269 			xodtemplate_contactgroup *cg;
6270 			char *ptr, *next_ptr;
6271 
6272 			for(next_ptr = ptr = temp_contactgroup->contactgroup_members; next_ptr; ptr = next_ptr + 1) {
6273 				next_ptr = strchr(ptr, ',');
6274 				if(next_ptr)
6275 					*next_ptr = 0;
6276 				while(*ptr == ' ' || *ptr == '\t')
6277 					ptr++;
6278 				strip(ptr);
6279 				if(!(cg = xodtemplate_find_real_contactgroup(ptr))) {
6280 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find member group '%s' specified in contactgroup '%s' (config file '%s', starting on line %d)\n", ptr, temp_contactgroup->contactgroup_name, xodtemplate_config_file_name(temp_contactgroup->_config_file), temp_contactgroup->_start_line);
6281 					return ERROR;
6282 					}
6283 				add_object_to_objectlist(&temp_contactgroup->group_list, cg);
6284 				}
6285 			my_free(temp_contactgroup->contactgroup_members);
6286 			}
6287 
6288 		/* move on if we have no members */
6289 		if(temp_contactgroup->members == NULL)
6290 			continue;
6291 
6292 		/* we might need this */
6293 		if(!use_precached_objects && !(temp_contactgroup->reject_map = bitmap_create(xodcount.contacts))) {
6294 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not create reject map for contactgroup '%s'", temp_contactgroup->contactgroup_name);
6295 			return ERROR;
6296 			}
6297 
6298 		/* get list of contacts in the contactgroup */
6299 		if(xodtemplate_expand_contacts(&accept, temp_contactgroup->reject_map, temp_contactgroup->members, temp_contactgroup->_config_file, temp_contactgroup->_start_line) != OK) {
6300 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Failed to expand contacts for contactgroup '%s' (config file '%s', starting at line %d)\n",
6301 				  temp_contactgroup->contactgroup_name,
6302 				  xodtemplate_config_file_name(temp_contactgroup->_config_file),
6303 				  temp_contactgroup->_start_line);
6304 			return ERROR;
6305 			}
6306 
6307 		my_free(temp_contactgroup->members);
6308 		for(list = accept; list; list = next) {
6309 			temp_contact = (xodtemplate_contact *)list->object_ptr;
6310 			next = list->next;
6311 			free(list);
6312 			xodtemplate_add_contactgroup_member(temp_contactgroup, temp_contact);
6313 			}
6314 		}
6315 
6316 	/* if we're using precached objects we can bail out now */
6317 	if(use_precached_objects)
6318 		return OK;
6319 
6320 	/* process all contacts with contactgroups directives */
6321 	for(temp_contact = xodtemplate_contact_list; temp_contact != NULL; temp_contact = temp_contact->next) {
6322 
6323 		/* skip contacts without contactgroup directives or contact names */
6324 		if(temp_contact->contact_groups == NULL || temp_contact->contact_name == NULL)
6325 			continue;
6326 
6327 		/* preprocess the contactgroup list, to change "grp1,grp2,grp3,!grp2" into "grp1,grp3" */
6328 		if((contactgroup_names = xodtemplate_process_contactgroup_names(temp_contact->contact_groups, temp_contact->_config_file, temp_contact->_start_line)) == NULL) {
6329 			logit(NSLOG_RUNTIME_ERROR, TRUE, "Error: Failed to process contactgroups for contact '%s' (config file '%s', starting at line %d)\n",
6330 				  temp_contact->contact_name, xodtemplate_config_file_name(temp_contact->_config_file),	temp_contact->_start_line);
6331 			return ERROR;
6332 			}
6333 
6334 		/* process the list of contactgroups */
6335 		for(temp_ptr = strtok(contactgroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) {
6336 
6337 			/* strip trailing spaces */
6338 			strip(temp_ptr);
6339 
6340 			/* find the contactgroup */
6341 			temp_contactgroup = xodtemplate_find_real_contactgroup(temp_ptr);
6342 			if(temp_contactgroup == NULL) {
6343 				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);
6344 				my_free(contactgroup_names);
6345 				return ERROR;
6346 				}
6347 
6348 			if(!temp_contactgroup->member_map && !(temp_contactgroup->member_map = bitmap_create(xodcount.contacts))) {
6349 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Failed to create member map for contactgroup '%s'\n",
6350 					  temp_contactgroup->contactgroup_name);
6351 				return ERROR;
6352 				}
6353 			/* add this contact to the contactgroup members directive */
6354 			xodtemplate_add_contactgroup_member(temp_contactgroup, temp_contact);
6355 			}
6356 
6357 		/* free memory */
6358 		my_free(contactgroup_names);
6359 		}
6360 
6361 	/* expand subgroup membership recursively */
6362 	for(temp_contactgroup = xodtemplate_contactgroup_list; temp_contactgroup; temp_contactgroup = temp_contactgroup->next) {
6363 		if(xodtemplate_recombobulate_contactgroup_subgroups(temp_contactgroup) != XOD_OK)
6364 			return ERROR;
6365 		/* rejects are no longer necessary */
6366 		bitmap_destroy(temp_contactgroup->reject_map);
6367 		/* make sure we don't recursively add subgroup members again */
6368 		free_objectlist(&temp_contactgroup->group_list);
6369 	}
6370 
6371 	return OK;
6372 	}
6373 
6374 
6375 
xodtemplate_recombobulate_hostgroup_subgroups(xodtemplate_hostgroup * temp_hostgroup)6376 static int xodtemplate_recombobulate_hostgroup_subgroups(xodtemplate_hostgroup *temp_hostgroup) {
6377 	objectlist *mlist, *glist;
6378 
6379 	if(temp_hostgroup == NULL)
6380 		return ERROR;
6381 
6382 	/* if this one's already handled somehow, we return early */
6383 	if(temp_hostgroup->loop_status != XOD_NEW)
6384 		return temp_hostgroup->loop_status;
6385 
6386 	/* mark this one as seen */
6387 	temp_hostgroup->loop_status = XOD_SEEN;
6388 
6389 	/* resolve included groups' members and add them to ours */
6390 	for(glist = temp_hostgroup->group_list; glist; glist = glist->next) {
6391 		int result;
6392 		xodtemplate_hostgroup *inc = (xodtemplate_hostgroup *)glist->object_ptr;
6393 		result = xodtemplate_recombobulate_hostgroup_subgroups(inc);
6394 		if(result != XOD_OK) {
6395 			if(result == ERROR)
6396 				return ERROR;
6397 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Hostgroups '%s' and '%s' part of a hostgroup_members include loop\n", temp_hostgroup->hostgroup_name, inc->hostgroup_name);
6398 			inc->loop_status = XOD_LOOPY;
6399 			temp_hostgroup->loop_status = XOD_LOOPY;
6400 			break;
6401 			}
6402 		for(mlist = inc->member_list; mlist; mlist = mlist->next) {
6403 			xodtemplate_host *h = (xodtemplate_host *)mlist->object_ptr;
6404 			if (xodtemplate_add_hostgroup_member(temp_hostgroup, mlist->object_ptr) != OK) {
6405 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Failed to add '%s' as a subgroup member host of hostgroup '%s' from hostgroup '%s'\n",
6406 					  h->host_name, temp_hostgroup->hostgroup_name, inc->hostgroup_name);
6407 				return ERROR;
6408 				}
6409 			}
6410 		}
6411 
6412 	if(temp_hostgroup->loop_status == XOD_SEEN)
6413 		temp_hostgroup->loop_status = XOD_OK;
6414 
6415 	return temp_hostgroup->loop_status;
6416 	}
6417 
6418 
6419 
6420 /* recombobulates hostgroup definitions */
xodtemplate_recombobulate_hostgroups(void)6421 int xodtemplate_recombobulate_hostgroups(void) {
6422 	xodtemplate_host *temp_host = NULL;
6423 	xodtemplate_hostgroup *temp_hostgroup = NULL;
6424 	char *hostgroup_names = NULL;
6425 	char *ptr = NULL;
6426 	char *next_ptr = NULL;
6427 	char *temp_ptr = NULL;
6428 	int result = 0;
6429 
6430 	/* 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 */
6431 	for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup; temp_hostgroup = temp_hostgroup->next) {
6432 		objectlist *next, *list, *accept = NULL;
6433 
6434 		/*
6435 		 * if the hostgroup has no accept or reject list and no group
6436 		 * members we don't need the bitmaps for it. bitmap_isset()
6437 		 * will return 0 when passed a NULL map, so we can safely use
6438 		 * that to add any items from the object list later.
6439 		 */
6440 		if(temp_hostgroup->members == NULL && temp_hostgroup->hostgroup_members == NULL)
6441 			continue;
6442 
6443 		/* we'll need the member_map */
6444 		if (!(temp_hostgroup->member_map = bitmap_create(xodcount.hosts))) {
6445 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not create member map for hostgroup '%s'\n", temp_hostgroup->hostgroup_name);
6446 			return ERROR;
6447 			}
6448 
6449 		/* resolve groups into a group-list */
6450 		for(next_ptr = ptr = temp_hostgroup->hostgroup_members; next_ptr; ptr = next_ptr + 1) {
6451 			xodtemplate_hostgroup *hg;
6452 			next_ptr = strchr(ptr, ',');
6453 			if(next_ptr)
6454 				*next_ptr = 0;
6455 			while(*ptr == ' ' || *ptr == '\t')
6456 				ptr++;
6457 
6458 			strip(ptr);
6459 
6460 			if (!(hg = xodtemplate_find_real_hostgroup(ptr))) {
6461 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find member group '%s' specified in hostgroup '%s' (config file '%s', starting on line %d)\n", ptr, temp_hostgroup->hostgroup_name, xodtemplate_config_file_name(temp_hostgroup->_config_file), temp_hostgroup->_start_line);
6462 				return ERROR;
6463 				}
6464 			add_object_to_objectlist(&temp_hostgroup->group_list, hg);
6465 			}
6466 
6467 		/* move on if we have no members */
6468 		if(temp_hostgroup->members == NULL)
6469 			continue;
6470 
6471 		/* we might need this */
6472 		if(!use_precached_objects && !(temp_hostgroup->reject_map = bitmap_create(xodcount.hosts))) {
6473 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not create reject map for hostgroup '%s'\n", temp_hostgroup->hostgroup_name);
6474 			return ERROR;
6475 			}
6476 
6477 		/* get list of hosts in the hostgroup */
6478 		result = xodtemplate_expand_hosts(&accept, temp_hostgroup->reject_map, temp_hostgroup->members, temp_hostgroup->_config_file, temp_hostgroup->_start_line);
6479 		if(result == ERROR || (accept == NULL && bitmap_count_set_bits(temp_hostgroup->reject_map) == 0)) {
6480 			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);
6481 			return ERROR;
6482 			}
6483 
6484 		my_free(temp_hostgroup->members);
6485 
6486 		for (list = accept; list; list = next) {
6487 			temp_host = (xodtemplate_host *)list->object_ptr;
6488 			next = list->next;
6489 			free(list);
6490 			xodtemplate_add_hostgroup_member(temp_hostgroup, temp_host);
6491 			}
6492 		}
6493 
6494 	/* if we're using precached objects we can bail out now */
6495 	if(use_precached_objects)
6496 		return OK;
6497 
6498 	/* process all hosts that have hostgroup directives */
6499 	for(temp_host = xodtemplate_host_list; temp_host != NULL; temp_host = temp_host->next) {
6500 
6501 		/* skip hosts without hostgroup directives or host names */
6502 		if(temp_host->host_groups == NULL || temp_host->host_name == NULL)
6503 			continue;
6504 
6505 		/* skip hosts that shouldn't be registered */
6506 		if(temp_host->register_object == FALSE)
6507 			continue;
6508 
6509 		/* preprocess the hostgroup list, to change "grp1,grp2,grp3,!grp2" into "grp1,grp3" */
6510 		/* 10/18/07 EG an empty return value means an error occurred */
6511 		if((hostgroup_names = xodtemplate_process_hostgroup_names(temp_host->host_groups, temp_host->_config_file, temp_host->_start_line)) == NULL) {
6512 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Failed to process hostgroup names for host '%s' (config file '%s', starting at line %d)\n",
6513 				  temp_host->host_name, xodtemplate_config_file_name(temp_host->_config_file), temp_host->_start_line);
6514 			return ERROR;
6515 			}
6516 
6517 		/* process the list of hostgroups */
6518 		for(temp_ptr = strtok(hostgroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) {
6519 
6520 			/* strip trailing spaces */
6521 			strip(temp_ptr);
6522 
6523 			/* find the hostgroup */
6524 			temp_hostgroup = xodtemplate_find_real_hostgroup(temp_ptr);
6525 			if(temp_hostgroup == NULL) {
6526 				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);
6527 				my_free(hostgroup_names);
6528 				return ERROR;
6529 				}
6530 			if(!temp_hostgroup->member_map && !(temp_hostgroup->member_map = bitmap_create(xodcount.hosts))) {
6531 				logit(NSLOG_CONFIG_ERROR, TRUE, "Failed to create bitmap to join host '%s' to group '%s'\n",
6532 					  temp_host->host_name, temp_hostgroup->hostgroup_name);
6533 				return ERROR;
6534 				}
6535 
6536 			/* add ourselves to the hostgroup member list */
6537 			xodtemplate_add_hostgroup_member(temp_hostgroup, temp_host);
6538 			}
6539 
6540 		/* free memory */
6541 		my_free(hostgroup_names);
6542 		}
6543 
6544 	/* expand subgroup membership recursively */
6545 	for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup; temp_hostgroup = temp_hostgroup->next) {
6546 		if(xodtemplate_recombobulate_hostgroup_subgroups(temp_hostgroup) != XOD_OK) {
6547 			return ERROR;
6548 			}
6549 		/* rejects are no longer necessary */
6550 		bitmap_destroy(temp_hostgroup->reject_map);
6551 		/* make sure we don't recursively add subgroup members again */
6552 		free_objectlist(&temp_hostgroup->group_list);
6553 		}
6554 
6555 	return OK;
6556 	}
6557 
6558 
6559 
xodtemplate_recombobulate_servicegroup_subgroups(xodtemplate_servicegroup * temp_servicegroup)6560 static int xodtemplate_recombobulate_servicegroup_subgroups(xodtemplate_servicegroup *temp_servicegroup) {
6561 	objectlist *mlist, *glist;
6562 
6563 	if(temp_servicegroup == NULL)
6564 		return ERROR;
6565 
6566 	if(temp_servicegroup->loop_status != XOD_NEW)
6567 		return temp_servicegroup->loop_status;
6568 
6569 	/* mark this as seen */
6570 	temp_servicegroup->loop_status = XOD_SEEN;
6571 
6572 	for(glist = temp_servicegroup->group_list; glist; glist = glist->next) {
6573 		int result;
6574 		xodtemplate_servicegroup *inc = (xodtemplate_servicegroup *)glist->object_ptr;
6575 
6576 		result = xodtemplate_recombobulate_servicegroup_subgroups(inc);
6577 		if(result != XOD_OK) {
6578 			if(result == ERROR)
6579 				return ERROR;
6580 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Servicegroups '%s' and '%s' are part of a servicegroup_members include loop\n",
6581 				  temp_servicegroup->servicegroup_name, inc->servicegroup_name);
6582 			inc->loop_status = XOD_LOOPY;
6583 			temp_servicegroup->loop_status = XOD_LOOPY;
6584 			break;
6585 			}
6586 		for(mlist = inc->member_list; mlist; mlist = mlist->next) {
6587 			xodtemplate_service *s = (xodtemplate_service *)mlist->object_ptr;
6588 			if(xodtemplate_add_servicegroup_member(temp_servicegroup, s) != OK) {
6589 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Failed to add service '%s' on host '%s' as a subgroup member of servicegroup '%s' from servicegroup '%s'\n",
6590 					  s->host_name, s->service_description, temp_servicegroup->servicegroup_name, inc->servicegroup_name);
6591 				return ERROR;
6592 				}
6593 			}
6594 		}
6595 
6596 	if(temp_servicegroup->loop_status == XOD_SEEN)
6597 		temp_servicegroup->loop_status = XOD_OK;
6598 
6599 	return temp_servicegroup->loop_status;
6600 	}
6601 
6602 /* recombobulates servicegroup definitions */
6603 /***** THIS NEEDS TO BE CALLED AFTER OBJECTS (SERVICES) ARE RESOLVED AND DUPLICATED *****/
xodtemplate_recombobulate_servicegroups(void)6604 int xodtemplate_recombobulate_servicegroups(void) {
6605 	xodtemplate_service *temp_service = NULL;
6606 	xodtemplate_servicegroup *temp_servicegroup = NULL;
6607 	char *servicegroup_names = NULL;
6608 	char *temp_ptr = NULL;
6609 	int result = 0;
6610 
6611 	/*
6612 	 * expand servicegroup members. We need this to get the rejected ones
6613 	 * before we add members from the servicelist.
6614 	 */
6615 	for(temp_servicegroup = xodtemplate_servicegroup_list; temp_servicegroup; temp_servicegroup = temp_servicegroup->next) {
6616 		objectlist *list, *next, *accept = NULL;
6617 
6618 		if(temp_servicegroup->members == NULL && temp_servicegroup->servicegroup_members == NULL)
6619 			continue;
6620 
6621 		/* we'll need the member map */
6622 		if(!(temp_servicegroup->member_map = bitmap_create(xodcount.services))) {
6623 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not create member map for servicegroup '%s'\n", temp_servicegroup->servicegroup_name);
6624 			return ERROR;
6625 			}
6626 
6627 		/* resolve groups into a group-list */
6628 		if(temp_servicegroup->servicegroup_members) {
6629 			xodtemplate_servicegroup *sg;
6630 			char *ptr, *next_ptr = NULL;
6631 			for(ptr = temp_servicegroup->servicegroup_members; ptr; ptr = next_ptr + 1) {
6632 				next_ptr = strchr(ptr, ',');
6633 				if(next_ptr)
6634 					*next_ptr = 0;
6635 				strip(ptr);
6636 				if(!(sg = xodtemplate_find_real_servicegroup(ptr))) {
6637 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not find member group '%s' specified in servicegroup '%s' (config file '%s', starting on line %d)\n", ptr, temp_servicegroup->servicegroup_name, xodtemplate_config_file_name(temp_servicegroup->_config_file), temp_servicegroup->_start_line);
6638 					return ERROR;
6639 
6640 				}
6641 				add_object_to_objectlist(&temp_servicegroup->group_list, sg);
6642 				if(!next_ptr)
6643 					break;
6644 				}
6645 			my_free(temp_servicegroup->servicegroup_members);
6646 			}
6647 
6648 		/* move on if we have no members */
6649 		if(temp_servicegroup->members == NULL)
6650 			continue;
6651 
6652 		/* we might need this */
6653 		if(!use_precached_objects && !(temp_servicegroup->reject_map = bitmap_create(xodcount.services))) {
6654 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not create reject map for hostgroup '%s'\n", temp_servicegroup->servicegroup_name);
6655 			return ERROR;
6656 			}
6657 
6658 		/* get list of service members in the servicegroup */
6659 		result = xodtemplate_expand_services(&accept, temp_servicegroup->reject_map, NULL, temp_servicegroup->members, temp_servicegroup->_config_file, temp_servicegroup->_start_line);
6660 		if(result == ERROR || (accept == NULL && bitmap_count_set_bits(temp_servicegroup->reject_map) == 0)) {
6661 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not expand members specified in servicegroup '%s' (config file '%s', starting at line %d)\n", temp_servicegroup->servicegroup_name, xodtemplate_config_file_name(temp_servicegroup->_config_file), temp_servicegroup->_start_line);
6662 			return ERROR;
6663 			}
6664 
6665 		/* we don't need this anymore */
6666 		my_free(temp_servicegroup->members);
6667 
6668 		for(list = accept; list; list = next) {
6669 			xodtemplate_service *s = (xodtemplate_service *)list->object_ptr;
6670 			next = list->next;
6671 			free(list);
6672 			xodtemplate_add_servicegroup_member(temp_servicegroup, s);
6673 			}
6674 		}
6675 
6676 	/* if we're using precached objects we can bail out now */
6677 	if(use_precached_objects == TRUE)
6678 		return OK;
6679 
6680 	/* Add services from 'servicegroups' directive */
6681 	for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) {
6682 
6683 		/* skip services without servicegroup directives or service names */
6684 		if(temp_service->service_groups == NULL || temp_service->host_name == NULL || temp_service->service_description == NULL)
6685 			continue;
6686 
6687 		/* skip services that shouldn't be registered */
6688 		if(temp_service->register_object == FALSE)
6689 			continue;
6690 
6691 		/* preprocess the servicegroup list, to change "grp1,grp2,grp3,!grp2" into "grp1,grp3" */
6692 		/* 10/19/07 EG an empty return value means an error occurred */
6693 		if((servicegroup_names = xodtemplate_process_servicegroup_names(temp_service->service_groups, temp_service->_config_file, temp_service->_start_line)) == NULL) {
6694 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Failed to process servicegroup names for service '%s' on host '%s' (config file '%s', starting at line %d)\n",
6695 				  temp_service->service_description, temp_service->host_name, xodtemplate_config_file_name(temp_service->_config_file), temp_service->_start_line);
6696 			return ERROR;
6697 			}
6698 
6699 		/* process the list of servicegroups */
6700 		for(temp_ptr = strtok(servicegroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) {
6701 
6702 			/* strip trailing spaces */
6703 			strip(temp_ptr);
6704 
6705 			/* find the servicegroup */
6706 			temp_servicegroup = xodtemplate_find_real_servicegroup(temp_ptr);
6707 			if(temp_servicegroup == NULL) {
6708 				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);
6709 				my_free(servicegroup_names);
6710 				return ERROR;
6711 				}
6712 
6713 			if(!temp_servicegroup->member_map && !(temp_servicegroup->member_map = bitmap_create(xodcount.services))) {
6714 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Failed to create member map for service group %s\n", temp_servicegroup->servicegroup_name);
6715 				return ERROR;
6716 				}
6717 			/* add ourselves as members to the group */
6718 			xodtemplate_add_servicegroup_member(temp_servicegroup, temp_service);
6719 		}
6720 
6721 		/* free servicegroup names */
6722 		my_free(servicegroup_names);
6723 		}
6724 
6725 	/* expand subgroup membership recursively */
6726 	for(temp_servicegroup = xodtemplate_servicegroup_list; temp_servicegroup; temp_servicegroup = temp_servicegroup->next) {
6727 		if(xodtemplate_recombobulate_servicegroup_subgroups(temp_servicegroup) != XOD_OK) {
6728 			return ERROR;
6729 			}
6730 		/* rejects are no longer necessary */
6731 		bitmap_destroy(temp_servicegroup->reject_map);
6732 		/* make sure we don't recursively add subgroup members again */
6733 		free_objectlist(&temp_servicegroup->group_list);
6734 		}
6735 
6736 	return OK;
6737 	}
6738 
6739 
6740 
6741 
6742 /******************************************************************/
6743 /******************* OBJECT SEARCH FUNCTIONS **********************/
6744 /******************************************************************/
6745 
6746 #ifdef NSCORE
6747 
6748 /* finds a specific timeperiod object */
xodtemplate_find_timeperiod(char * name)6749 xodtemplate_timeperiod *xodtemplate_find_timeperiod(char *name) {
6750 	xodtemplate_timeperiod temp_timeperiod;
6751 
6752 	if(name == NULL)
6753 		return NULL;
6754 
6755 	temp_timeperiod.name = name;
6756 
6757 	return skiplist_find_first(xobject_template_skiplists[TIMEPERIOD_SKIPLIST], &temp_timeperiod, NULL);
6758 	}
6759 
6760 
6761 /* finds a specific command object */
xodtemplate_find_command(char * name)6762 xodtemplate_command *xodtemplate_find_command(char *name) {
6763 	xodtemplate_command temp_command;
6764 
6765 	if(name == NULL)
6766 		return NULL;
6767 
6768 	temp_command.name = name;
6769 
6770 	return skiplist_find_first(xobject_template_skiplists[COMMAND_SKIPLIST], &temp_command, NULL);
6771 	}
6772 
6773 #endif
6774 
6775 /* finds a specific contactgroup object */
xodtemplate_find_contactgroup(char * name)6776 xodtemplate_contactgroup *xodtemplate_find_contactgroup(char *name) {
6777 	xodtemplate_contactgroup temp_contactgroup;
6778 
6779 	if(name == NULL)
6780 		return NULL;
6781 
6782 	temp_contactgroup.name = name;
6783 
6784 	return skiplist_find_first(xobject_template_skiplists[CONTACTGROUP_SKIPLIST], &temp_contactgroup, NULL);
6785 	}
6786 
6787 
6788 /* finds a specific contactgroup object by its REAL name, not its TEMPLATE name */
xodtemplate_find_real_contactgroup(char * name)6789 xodtemplate_contactgroup *xodtemplate_find_real_contactgroup(char *name) {
6790 	xodtemplate_contactgroup temp_contactgroup;
6791 
6792 	if(name == NULL)
6793 		return NULL;
6794 
6795 	temp_contactgroup.contactgroup_name = name;
6796 
6797 	return skiplist_find_first(xobject_skiplists[CONTACTGROUP_SKIPLIST], &temp_contactgroup, NULL);
6798 	}
6799 
6800 
6801 /* finds a specific hostgroup object */
xodtemplate_find_hostgroup(char * name)6802 xodtemplate_hostgroup *xodtemplate_find_hostgroup(char *name) {
6803 	xodtemplate_hostgroup temp_hostgroup;
6804 
6805 	if(name == NULL)
6806 		return NULL;
6807 
6808 	temp_hostgroup.name = name;
6809 
6810 	return skiplist_find_first(xobject_template_skiplists[HOSTGROUP_SKIPLIST], &temp_hostgroup, NULL);
6811 	}
6812 
6813 
6814 /* finds a specific hostgroup object by its REAL name, not its TEMPLATE name */
xodtemplate_find_real_hostgroup(char * name)6815 xodtemplate_hostgroup *xodtemplate_find_real_hostgroup(char *name) {
6816 	xodtemplate_hostgroup temp_hostgroup;
6817 
6818 	if(name == NULL)
6819 		return NULL;
6820 
6821 	temp_hostgroup.hostgroup_name = name;
6822 
6823 	return skiplist_find_first(xobject_skiplists[HOSTGROUP_SKIPLIST], &temp_hostgroup, NULL);
6824 	}
6825 
6826 
6827 /* finds a specific servicegroup object */
xodtemplate_find_servicegroup(char * name)6828 xodtemplate_servicegroup *xodtemplate_find_servicegroup(char *name) {
6829 	xodtemplate_servicegroup temp_servicegroup;
6830 
6831 	if(name == NULL)
6832 		return NULL;
6833 
6834 	temp_servicegroup.name = name;
6835 
6836 	return skiplist_find_first(xobject_template_skiplists[SERVICEGROUP_SKIPLIST], &temp_servicegroup, NULL);
6837 	}
6838 
6839 
6840 /* finds a specific servicegroup object by its REAL name, not its TEMPLATE name */
xodtemplate_find_real_servicegroup(char * name)6841 xodtemplate_servicegroup *xodtemplate_find_real_servicegroup(char *name) {
6842 	xodtemplate_servicegroup temp_servicegroup;
6843 
6844 	if(name == NULL)
6845 		return NULL;
6846 
6847 	temp_servicegroup.servicegroup_name = name;
6848 
6849 	return skiplist_find_first(xobject_skiplists[SERVICEGROUP_SKIPLIST], &temp_servicegroup, NULL);
6850 	}
6851 
6852 
6853 /* finds a specific servicedependency object */
xodtemplate_find_servicedependency(char * name)6854 xodtemplate_servicedependency *xodtemplate_find_servicedependency(char *name) {
6855 	xodtemplate_servicedependency temp_servicedependency;
6856 
6857 	if(name == NULL)
6858 		return NULL;
6859 
6860 	temp_servicedependency.name = name;
6861 
6862 	return skiplist_find_first(xobject_template_skiplists[SERVICEDEPENDENCY_SKIPLIST], &temp_servicedependency, NULL);
6863 	}
6864 
6865 
6866 /* finds a specific serviceescalation object */
xodtemplate_find_serviceescalation(char * name)6867 xodtemplate_serviceescalation *xodtemplate_find_serviceescalation(char *name) {
6868 	xodtemplate_serviceescalation temp_serviceescalation;
6869 
6870 	if(name == NULL)
6871 		return NULL;
6872 
6873 	temp_serviceescalation.name = name;
6874 
6875 	return skiplist_find_first(xobject_template_skiplists[SERVICEESCALATION_SKIPLIST], &temp_serviceescalation, NULL);
6876 	}
6877 
6878 
6879 /* finds a specific contact object */
xodtemplate_find_contact(char * name)6880 xodtemplate_contact *xodtemplate_find_contact(char *name) {
6881 	xodtemplate_contact temp_contact;
6882 
6883 	if(name == NULL)
6884 		return NULL;
6885 
6886 	temp_contact.name = name;
6887 
6888 	return skiplist_find_first(xobject_template_skiplists[CONTACT_SKIPLIST], &temp_contact, NULL);
6889 	}
6890 
6891 
6892 /* finds a specific contact object by its REAL name, not its TEMPLATE name */
xodtemplate_find_real_contact(char * name)6893 xodtemplate_contact *xodtemplate_find_real_contact(char *name) {
6894 	xodtemplate_contact temp_contact;
6895 
6896 	if(name == NULL)
6897 		return NULL;
6898 
6899 	temp_contact.contact_name = name;
6900 
6901 	return skiplist_find_first(xobject_skiplists[CONTACT_SKIPLIST], &temp_contact, NULL);
6902 	}
6903 
6904 
6905 /* finds a specific host object */
xodtemplate_find_host(char * name)6906 xodtemplate_host *xodtemplate_find_host(char *name) {
6907 	xodtemplate_host temp_host;
6908 
6909 	if(name == NULL)
6910 		return NULL;
6911 
6912 	temp_host.name = name;
6913 
6914 	return skiplist_find_first(xobject_template_skiplists[HOST_SKIPLIST], &temp_host, NULL);
6915 	}
6916 
6917 
6918 /* finds a specific host object by its REAL name, not its TEMPLATE name */
xodtemplate_find_real_host(char * name)6919 xodtemplate_host *xodtemplate_find_real_host(char *name) {
6920 	xodtemplate_host temp_host;
6921 
6922 	if(name == NULL)
6923 		return NULL;
6924 
6925 	temp_host.host_name = name;
6926 
6927 	return skiplist_find_first(xobject_skiplists[HOST_SKIPLIST], &temp_host, NULL);
6928 	}
6929 
6930 
6931 /* finds a specific hostdependency object */
xodtemplate_find_hostdependency(char * name)6932 xodtemplate_hostdependency *xodtemplate_find_hostdependency(char *name) {
6933 	xodtemplate_hostdependency temp_hostdependency;
6934 
6935 	if(name == NULL)
6936 		return NULL;
6937 
6938 	temp_hostdependency.name = name;
6939 
6940 	return skiplist_find_first(xobject_template_skiplists[HOSTDEPENDENCY_SKIPLIST], &temp_hostdependency, NULL);
6941 	}
6942 
6943 
6944 /* finds a specific hostescalation object */
xodtemplate_find_hostescalation(char * name)6945 xodtemplate_hostescalation *xodtemplate_find_hostescalation(char *name) {
6946 	xodtemplate_hostescalation temp_hostescalation;
6947 
6948 	if(name == NULL)
6949 		return NULL;
6950 
6951 	temp_hostescalation.name = name;
6952 
6953 	return skiplist_find_first(xobject_template_skiplists[HOSTESCALATION_SKIPLIST], &temp_hostescalation, NULL);
6954 	}
6955 
6956 
6957 /* finds a specific hostextinfo object */
xodtemplate_find_hostextinfo(char * name)6958 xodtemplate_hostextinfo *xodtemplate_find_hostextinfo(char *name) {
6959 	xodtemplate_hostextinfo temp_hostextinfo;
6960 
6961 	if(name == NULL)
6962 		return NULL;
6963 
6964 	temp_hostextinfo.name = name;
6965 
6966 	return skiplist_find_first(xobject_template_skiplists[HOSTEXTINFO_SKIPLIST], &temp_hostextinfo, NULL);
6967 	}
6968 
6969 
6970 /* finds a specific serviceextinfo object */
xodtemplate_find_serviceextinfo(char * name)6971 xodtemplate_serviceextinfo *xodtemplate_find_serviceextinfo(char *name) {
6972 	xodtemplate_serviceextinfo temp_serviceextinfo;
6973 
6974 	if(name == NULL)
6975 		return NULL;
6976 
6977 	temp_serviceextinfo.name = name;
6978 
6979 	return skiplist_find_first(xobject_template_skiplists[SERVICEEXTINFO_SKIPLIST], &temp_serviceextinfo, NULL);
6980 	}
6981 
6982 
6983 /* finds a specific service object */
xodtemplate_find_service(char * name)6984 xodtemplate_service *xodtemplate_find_service(char *name) {
6985 	xodtemplate_service temp_service;
6986 
6987 	if(name == NULL)
6988 		return NULL;
6989 
6990 	temp_service.name = name;
6991 
6992 	return skiplist_find_first(xobject_template_skiplists[SERVICE_SKIPLIST], &temp_service, NULL);
6993 	}
6994 
6995 /* finds a specific service object by its REAL name, not its TEMPLATE name */
xodtemplate_find_real_service(char * host_name,char * service_description)6996 xodtemplate_service *xodtemplate_find_real_service(char *host_name, char *service_description) {
6997 	xodtemplate_service temp_service;
6998 
6999 	if(host_name == NULL || service_description == NULL)
7000 		return NULL;
7001 
7002 	temp_service.host_name = host_name;
7003 	temp_service.service_description = service_description;
7004 
7005 	return skiplist_find_first(xobject_skiplists[SERVICE_SKIPLIST], &temp_service, NULL);
7006 	}
7007 
7008 
7009 
7010 
7011 /******************************************************************/
7012 /**************** OBJECT REGISTRATION FUNCTIONS *******************/
7013 /******************************************************************/
7014 
xodtemplate_register_contactgroup_members(xodtemplate_contactgroup * this_contactgroup)7015 static int xodtemplate_register_contactgroup_members(xodtemplate_contactgroup *this_contactgroup)
7016 {
7017 	objectlist *list;
7018 	struct contactgroup *cg;
7019 	int num_regs = 0;
7020 
7021 	if (!this_contactgroup->register_object)
7022 		return 0;
7023 
7024 	cg = find_contactgroup(this_contactgroup->contactgroup_name);
7025 	for(list = this_contactgroup->member_list; list; list = list->next) {
7026 		xodtemplate_contact *c = (xodtemplate_contact *)list->object_ptr;
7027 		if (!add_contact_to_contactgroup(cg, c->contact_name)) {
7028 			logit(NSLOG_CONFIG_ERROR, TRUE, "Bad member of contactgroup '%s' (config file '%s', starting on line %d)\n", cg->group_name, xodtemplate_config_file_name(this_contactgroup->_config_file), this_contactgroup->_start_line);
7029 			return -1;
7030 			}
7031 		num_regs++;
7032 		}
7033 	return num_regs;
7034 }
7035 
xodtemplate_register_hostgroup_members(xodtemplate_hostgroup * this_hostgroup)7036 static int xodtemplate_register_hostgroup_members(xodtemplate_hostgroup *this_hostgroup)
7037 {
7038 	objectlist *list;
7039 	struct hostgroup *hg;
7040 	int num_regs = 0;
7041 
7042 	if (!this_hostgroup->register_object)
7043 		return 0;
7044 
7045 	hg = find_hostgroup(this_hostgroup->hostgroup_name);
7046 	for(list = this_hostgroup->member_list; list; list = list->next) {
7047 		xodtemplate_host *h = (xodtemplate_host *)list->object_ptr;
7048 		if (!add_host_to_hostgroup(hg, h->host_name)) {
7049 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Bad member of hostgroup '%s' (config file '%s', starting on line %d)\n", hg->group_name, xodtemplate_config_file_name(this_hostgroup->_config_file), this_hostgroup->_start_line);
7050 			return -1;
7051 			}
7052 		num_regs++;
7053 		}
7054 	return num_regs;
7055 	}
7056 
xodtemplate_register_servicegroup_members(xodtemplate_servicegroup * this_servicegroup)7057 static int xodtemplate_register_servicegroup_members(xodtemplate_servicegroup *this_servicegroup)
7058 {
7059 	objectlist *list, *next;
7060 	struct servicegroup *sg;
7061 	int num_regs = 0;
7062 
7063 	if (!this_servicegroup->register_object)
7064 		return 0;
7065 
7066 	sg = find_servicegroup(this_servicegroup->servicegroup_name);
7067 	for(list = this_servicegroup->member_list; list; list = next) {
7068 		xodtemplate_service *s = (xodtemplate_service *)list->object_ptr;
7069 		next = list->next;
7070 		if (!add_service_to_servicegroup(sg, s->host_name, s->service_description)) {
7071 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Bad member of servicegroup '%s' (config file '%s', starting on line %d)\n", sg->group_name, xodtemplate_config_file_name(this_servicegroup->_config_file), this_servicegroup->_start_line);
7072 			return -1;
7073 			}
7074 		num_regs++;
7075 		}
7076 
7077 	return num_regs;
7078 	}
7079 
7080 /*
7081  * registers object definitions
7082  * The order goes like this:
7083  *   Timeperiods
7084  *   Commands
7085  *   Contactgroups
7086  *   Hostgroups
7087  *   Servicegroups
7088  *   Contacts
7089  *   Hosts
7090  *   Services
7091  *   Servicedependencies
7092  *   Serviceescalations
7093  *   Hostdependencies
7094  *   Hostescalations
7095  *
7096  * Why are contactgroups done before contacts? A reasonable assumption
7097  * would be that contacts should be flattened and added to the checked
7098  * objects directly rather than forcing us to fiddle with that crap
7099  * during runtime.
7100  */
xodtemplate_register_objects(void)7101 int xodtemplate_register_objects(void) {
7102 	unsigned int i;
7103 	int mcount;
7104 	xodtemplate_timeperiod *temp_timeperiod = NULL;
7105 	xodtemplate_command *temp_command = NULL;
7106 	xodtemplate_contactgroup *temp_contactgroup = NULL;
7107 	xodtemplate_hostgroup *temp_hostgroup = NULL;
7108 	xodtemplate_servicegroup *temp_servicegroup = NULL;
7109 	xodtemplate_contact *temp_contact = NULL;
7110 	xodtemplate_host *temp_host = NULL;
7111 	xodtemplate_service *temp_service = NULL;
7112 	void *ptr = NULL;
7113 	xodtemplate_hostdependency *hd, *next_hd;
7114 	xodtemplate_hostescalation *he, *next_he;
7115 	xodtemplate_servicedependency *sd, *next_sd;
7116 	xodtemplate_serviceescalation *se, *next_se;
7117 	unsigned int ocount[NUM_OBJECT_SKIPLISTS];
7118 	unsigned int tot_members = 0;
7119 
7120 
7121 	for (i = 0; i < ARRAY_SIZE(ocount); i++) {
7122 		ocount[i] = (unsigned int)skiplist_num_items(xobject_skiplists[i]);
7123 	}
7124 
7125 	/* dependencies are handled specially */
7126 	ocount[SERVICEDEPENDENCY_SKIPLIST] = 0;
7127 	ocount[HOSTDEPENDENCY_SKIPLIST] = 0;
7128 	ocount[HOSTESCALATION_SKIPLIST] = xodcount.hostescalations;
7129 	ocount[SERVICEESCALATION_SKIPLIST] = xodcount.serviceescalations;
7130 
7131 	if (create_object_tables(ocount) != OK) {
7132 		logit(NSLOG_CONFIG_ERROR, TRUE, "Failed to create object tables\n");
7133 		return ERROR;
7134 	}
7135 
7136 	/* register timeperiods */
7137 	ptr = NULL;
7138 	for(temp_timeperiod = (xodtemplate_timeperiod *)skiplist_get_first(xobject_skiplists[TIMEPERIOD_SKIPLIST], &ptr); temp_timeperiod != NULL; temp_timeperiod = (xodtemplate_timeperiod *)skiplist_get_next(&ptr)) {
7139 		if(xodtemplate_register_timeperiod(temp_timeperiod) == ERROR)
7140 			return ERROR;
7141 		}
7142 	timing_point("%u timeperiods registered\n", num_objects.timeperiods);
7143 
7144 	/* register commands */
7145 	ptr = NULL;
7146 	for(temp_command = (xodtemplate_command *)skiplist_get_first(xobject_skiplists[COMMAND_SKIPLIST], &ptr); temp_command != NULL; temp_command = (xodtemplate_command *)skiplist_get_next(&ptr)) {
7147 		if(xodtemplate_register_command(temp_command) == ERROR)
7148 			return ERROR;
7149 		}
7150 	timing_point("%u commands registered\n", num_objects.commands);
7151 
7152 	/* register contactgroups */
7153 	ptr = NULL;
7154 	for(temp_contactgroup = (xodtemplate_contactgroup *)skiplist_get_first(xobject_skiplists[CONTACTGROUP_SKIPLIST], &ptr); temp_contactgroup != NULL; temp_contactgroup = (xodtemplate_contactgroup *)skiplist_get_next(&ptr)) {
7155 		if(xodtemplate_register_contactgroup(temp_contactgroup) == ERROR)
7156 			return ERROR;
7157 		}
7158 	timing_point("%u contactgroups registered\n", num_objects.contactgroups);
7159 
7160 	/* register hostgroups */
7161 	ptr = NULL;
7162 	for(temp_hostgroup = (xodtemplate_hostgroup *)skiplist_get_first(xobject_skiplists[HOSTGROUP_SKIPLIST], &ptr); temp_hostgroup != NULL; temp_hostgroup = (xodtemplate_hostgroup *)skiplist_get_next(&ptr)) {
7163 		if(xodtemplate_register_hostgroup(temp_hostgroup) == ERROR)
7164 			return ERROR;
7165 		}
7166 	timing_point("%u hostgroups registered\n", num_objects.hostgroups);
7167 
7168 	/* register servicegroups */
7169 	ptr = NULL;
7170 	for(temp_servicegroup = (xodtemplate_servicegroup *)skiplist_get_first(xobject_skiplists[SERVICEGROUP_SKIPLIST], &ptr); temp_servicegroup != NULL; temp_servicegroup = (xodtemplate_servicegroup *)skiplist_get_next(&ptr)) {
7171 		if(xodtemplate_register_servicegroup(temp_servicegroup) == ERROR)
7172 			return ERROR;
7173 		}
7174 	timing_point("%u servicegroups registered\n", num_objects.servicegroups);
7175 
7176 	/* register contacts */
7177 	ptr = NULL;
7178 	for(temp_contact = (xodtemplate_contact *)skiplist_get_first(xobject_skiplists[CONTACT_SKIPLIST], &ptr); temp_contact != NULL; temp_contact = (xodtemplate_contact *)skiplist_get_next(&ptr)) {
7179 		if(xodtemplate_register_contact(temp_contact) == ERROR)
7180 			return ERROR;
7181 		}
7182 	timing_point("%u contacts registered\n", num_objects.contacts);
7183 
7184 	/* register hosts */
7185 	ptr = NULL;
7186 	for(temp_host = (xodtemplate_host *)skiplist_get_first(xobject_skiplists[HOST_SKIPLIST], &ptr); temp_host != NULL; temp_host = (xodtemplate_host *)skiplist_get_next(&ptr)) {
7187 		if(xodtemplate_register_host(temp_host) == ERROR)
7188 			return ERROR;
7189 		}
7190 	timing_point("%u hosts registered\n", num_objects.hosts);
7191 
7192 	/* register services */
7193 	ptr = NULL;
7194 	for(temp_service = (xodtemplate_service *)skiplist_get_first(xobject_skiplists[SERVICE_SKIPLIST], &ptr); temp_service != NULL; temp_service = (xodtemplate_service *)skiplist_get_next(&ptr)) {
7195 		if(xodtemplate_register_service(temp_service) == ERROR)
7196 			return ERROR;
7197 		}
7198 	timing_point("%u services registered\n", num_objects.services);
7199 
7200 	/* groups and objects are registered, so join them up */
7201 	/* register contactgroup members */
7202 	ptr = NULL; tot_members = 0;
7203 	for(temp_contactgroup = (xodtemplate_contactgroup *)skiplist_get_first(xobject_skiplists[CONTACTGROUP_SKIPLIST], &ptr); temp_contactgroup != NULL; temp_contactgroup = (xodtemplate_contactgroup *)skiplist_get_next(&ptr)) {
7204 		if((mcount = xodtemplate_register_contactgroup_members(temp_contactgroup)) < 0)
7205 			return ERROR;
7206 		tot_members += mcount;
7207 		}
7208 	timing_point("%u contactgroup memberships registered\n", tot_members);
7209 
7210 	/* register hostgroup members */
7211 	ptr = NULL; tot_members = 0;
7212 	for(temp_hostgroup = (xodtemplate_hostgroup *)skiplist_get_first(xobject_skiplists[HOSTGROUP_SKIPLIST], &ptr); temp_hostgroup != NULL; temp_hostgroup = (xodtemplate_hostgroup *)skiplist_get_next(&ptr)) {
7213 		if((mcount = xodtemplate_register_hostgroup_members(temp_hostgroup)) < 0)
7214 			return ERROR;
7215 		tot_members += mcount;
7216 		}
7217 	timing_point("%u hostgroup memberships registered\n", tot_members);
7218 
7219 	/* register servicegroup members */
7220 	ptr = NULL; tot_members = 0;
7221 	for(temp_servicegroup = (xodtemplate_servicegroup *)skiplist_get_first(xobject_skiplists[SERVICEGROUP_SKIPLIST], &ptr); temp_servicegroup != NULL; temp_servicegroup = (xodtemplate_servicegroup *)skiplist_get_next(&ptr)) {
7222 		if((mcount = xodtemplate_register_servicegroup_members(temp_servicegroup)) < 0)
7223 			return ERROR;
7224 		tot_members += mcount;
7225 		}
7226 	timing_point("%u servicegroup memberships registered\n", tot_members);
7227 
7228 	/*
7229 	 * These aren't in skiplists at all, but it's safe to destroy
7230 	 * them as we go along, since all dupes are at the head of the list
7231 	 */
7232 	if(xodtemplate_servicedependency_list) {
7233 		parent_map = bitmap_create(xodcount.services);
7234 		if(!parent_map) {
7235 			logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Failed to create parent bitmap for service dependencies\n");
7236 			return ERROR;
7237 			}
7238 		for(sd = xodtemplate_servicedependency_list; sd; sd = next_sd) {
7239 			next_sd = sd->next;
7240 #ifdef NSCGI
7241 			if(xodtemplate_register_servicedependency(sd) == ERROR)
7242 				return ERROR;
7243 #else
7244 			if(xodtemplate_register_and_destroy_servicedependency(sd) == ERROR)
7245 				return ERROR;
7246 #endif
7247 			}
7248 		bitmap_destroy(parent_map);
7249 		parent_map = NULL;
7250 		}
7251 	timing_point("%u unique / %u total servicedependencies registered\n",
7252 				 num_objects.servicedependencies, xodcount.servicedependencies);
7253 
7254 	for(se = xodtemplate_serviceescalation_list; se; se = next_se) {
7255 		next_se = se->next;
7256 		if(xodtemplate_register_and_destroy_serviceescalation(se) == ERROR)
7257 			return ERROR;
7258 		}
7259 	timing_point("%u serviceescalations registered\n", num_objects.serviceescalations);
7260 
7261 	for(hd = xodtemplate_hostdependency_list; hd; hd = next_hd) {
7262 		next_hd = hd->next;
7263 #ifdef NSCGI
7264 		if(xodtemplate_register_hostdependency(hd) == ERROR)
7265 			return ERROR;
7266 #else
7267 		if(xodtemplate_register_and_destroy_hostdependency(hd) == ERROR)
7268 			return ERROR;
7269 #endif
7270 		}
7271 	timing_point("%u unique / %u total hostdependencies registered\n",
7272 				 num_objects.hostdependencies, xodcount.hostdependencies);
7273 
7274 	for(he = xodtemplate_hostescalation_list; he; he = next_he) {
7275 		next_he = he->next;
7276 		if(xodtemplate_register_and_destroy_hostescalation(he) == ERROR)
7277 			return ERROR;
7278 		}
7279 	timing_point("%u hostescalations registered\n", num_objects.hostescalations);
7280 
7281 	return OK;
7282 	}
7283 
7284 
7285 
7286 /* registers a timeperiod definition */
xodtemplate_register_timeperiod(xodtemplate_timeperiod * this_timeperiod)7287 int xodtemplate_register_timeperiod(xodtemplate_timeperiod *this_timeperiod) {
7288 	xodtemplate_daterange *temp_daterange = NULL;
7289 	timeperiod *new_timeperiod = NULL;
7290 	daterange *new_daterange = NULL;
7291 	timerange *new_timerange = NULL;
7292 	timeperiodexclusion *new_timeperiodexclusion = NULL;
7293 	int day = 0;
7294 	int range = 0;
7295 	int x = 0;
7296 	char *day_range_ptr = NULL;
7297 	char *day_range_start_buffer = NULL;
7298 	char *temp_ptr = NULL;
7299 	unsigned long range_start_time = 0L;
7300 	unsigned long range_end_time = 0L;
7301 
7302 
7303 	/* bail out if we shouldn't register this object */
7304 	if(this_timeperiod->register_object == FALSE)
7305 		return OK;
7306 
7307 	/* add the timeperiod */
7308 	new_timeperiod = add_timeperiod(this_timeperiod->timeperiod_name, this_timeperiod->alias);
7309 
7310 	/* return with an error if we couldn't add the timeperiod */
7311 	if(new_timeperiod == NULL) {
7312 		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);
7313 		return ERROR;
7314 		}
7315 
7316 	/* add all exceptions to timeperiod */
7317 	for(x = 0; x < DATERANGE_TYPES; x++) {
7318 		for(temp_daterange = this_timeperiod->exceptions[x]; temp_daterange != NULL; temp_daterange = temp_daterange->next) {
7319 
7320 			/* skip null entries */
7321 			if(temp_daterange->timeranges == NULL || !strcmp(temp_daterange->timeranges, XODTEMPLATE_NULL))
7322 				continue;
7323 
7324 			/* add new exception to timeperiod */
7325 			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);
7326 			if(new_daterange == NULL) {
7327 				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);
7328 				return ERROR;
7329 				}
7330 
7331 			/* add timeranges to exception */
7332 			day_range_ptr = temp_daterange->timeranges;
7333 			range = 0;
7334 			for(day_range_start_buffer = my_strsep(&day_range_ptr, ", "); day_range_start_buffer != NULL; day_range_start_buffer = my_strsep(&day_range_ptr, ", ")) {
7335 
7336 				range++;
7337 
7338 				/* get time ranges */
7339 				if(xodtemplate_get_time_ranges(day_range_start_buffer, &range_start_time, &range_end_time) == ERROR) {
7340 					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);
7341 					return ERROR;
7342 					}
7343 
7344 				/* add the new time range to the date range */
7345 				new_timerange = add_timerange_to_daterange(new_daterange, range_start_time, range_end_time);
7346 				if(new_timerange == NULL) {
7347 					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);
7348 					return ERROR;
7349 					}
7350 				}
7351 			}
7352 		}
7353 
7354 	/* add all necessary timeranges to timeperiod */
7355 	for(day = 0; day < 7; day++) {
7356 
7357 		/* skip null entries */
7358 		if(this_timeperiod->timeranges[day] == NULL || !strcmp(this_timeperiod->timeranges[day], XODTEMPLATE_NULL))
7359 			continue;
7360 
7361 		day_range_ptr = this_timeperiod->timeranges[day];
7362 		range = 0;
7363 		for(day_range_start_buffer = my_strsep(&day_range_ptr, ", "); day_range_start_buffer != NULL; day_range_start_buffer = my_strsep(&day_range_ptr, ", ")) {
7364 
7365 			range++;
7366 
7367 			/* get time ranges */
7368 			if(xodtemplate_get_time_ranges(day_range_start_buffer, &range_start_time, &range_end_time) == ERROR) {
7369 				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);
7370 				return ERROR;
7371 				}
7372 
7373 			/* add the new time range to the time period */
7374 			new_timerange = add_timerange_to_timeperiod(new_timeperiod, day, range_start_time, range_end_time);
7375 			if(new_timerange == NULL) {
7376 				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);
7377 				return ERROR;
7378 				}
7379 			}
7380 
7381 		}
7382 
7383 	/* add timeperiod exclusions */
7384 	if(this_timeperiod->exclusions) {
7385 		for(temp_ptr = strtok(this_timeperiod->exclusions, ","); temp_ptr != NULL; temp_ptr = strtok(NULL, ",")) {
7386 			strip(temp_ptr);
7387 			new_timeperiodexclusion = add_exclusion_to_timeperiod(new_timeperiod, temp_ptr);
7388 			if(new_timeperiodexclusion == NULL) {
7389 				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);
7390 				return ERROR;
7391 				}
7392 			}
7393 		}
7394 
7395 	return OK;
7396 	}
7397 
7398 
7399 
7400 /* parses timerange string into start and end minutes */
xodtemplate_get_time_ranges(char * buf,unsigned long * range_start,unsigned long * range_end)7401 int xodtemplate_get_time_ranges(char *buf, unsigned long *range_start, unsigned long *range_end) {
7402 	char *range_ptr = NULL;
7403 	char *range_buffer = NULL;
7404 	char *time_ptr = NULL;
7405 	char *time_buffer = NULL;
7406 	int hours = 0;
7407 	int minutes = 0;
7408 
7409 	if(buf == NULL || range_start == NULL || range_end == NULL)
7410 		return ERROR;
7411 
7412 	range_ptr = buf;
7413 	range_buffer = my_strsep(&range_ptr, "-");
7414 	if(range_buffer == NULL)
7415 		return ERROR;
7416 
7417 	time_ptr = range_buffer;
7418 	time_buffer = my_strsep(&time_ptr, ":");
7419 	if(time_buffer == NULL)
7420 		return ERROR;
7421 	hours = atoi(time_buffer);
7422 
7423 	time_buffer = my_strsep(&time_ptr, ":");
7424 	if(time_buffer == NULL)
7425 		return ERROR;
7426 	minutes = atoi(time_buffer);
7427 
7428 	/* calculate the range start time in seconds */
7429 	*range_start = (unsigned long)((minutes * 60) + (hours * 60 * 60));
7430 
7431 	range_buffer = my_strsep(&range_ptr, "-");
7432 	if(range_buffer == NULL)
7433 		return ERROR;
7434 
7435 	time_ptr = range_buffer;
7436 	time_buffer = my_strsep(&time_ptr, ":");
7437 	if(time_buffer == NULL)
7438 		return ERROR;
7439 	hours = atoi(time_buffer);
7440 
7441 	time_buffer = my_strsep(&time_ptr, ":");
7442 	if(time_buffer == NULL)
7443 		return ERROR;
7444 	minutes = atoi(time_buffer);
7445 
7446 	/* calculate the range end time in seconds */
7447 	*range_end = (unsigned long)((minutes * 60) + (hours * 3600));
7448 
7449 	return OK;
7450 	}
7451 
7452 
7453 
7454 /* registers a command definition */
xodtemplate_register_command(xodtemplate_command * this_command)7455 int xodtemplate_register_command(xodtemplate_command *this_command) {
7456 	command *new_command = NULL;
7457 
7458 	/* bail out if we shouldn't register this object */
7459 	if(this_command->register_object == FALSE)
7460 		return OK;
7461 
7462 	/* add the command */
7463 	new_command = add_command(this_command->command_name, this_command->command_line);
7464 
7465 	/* return with an error if we couldn't add the command */
7466 	if(new_command == NULL) {
7467 		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);
7468 		return ERROR;
7469 		}
7470 
7471 	return OK;
7472 	}
7473 
7474 
7475 /* registers a contactgroup definition */
xodtemplate_register_contactgroup(xodtemplate_contactgroup * this_contactgroup)7476 int xodtemplate_register_contactgroup(xodtemplate_contactgroup *this_contactgroup) {
7477 	contactgroup *new_contactgroup = NULL;
7478 
7479 	/* bail out if we shouldn't register this object */
7480 	if(this_contactgroup->register_object == FALSE)
7481 		return OK;
7482 
7483 	/* add the contact group */
7484 	new_contactgroup = add_contactgroup(this_contactgroup->contactgroup_name, this_contactgroup->alias);
7485 
7486 	/* return with an error if we couldn't add the contactgroup */
7487 	if(new_contactgroup == NULL) {
7488 		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);
7489 		return ERROR;
7490 		}
7491 
7492 	return OK;
7493 	}
7494 
7495 
7496 
7497 /* registers a hostgroup definition */
xodtemplate_register_hostgroup(xodtemplate_hostgroup * this_hostgroup)7498 int xodtemplate_register_hostgroup(xodtemplate_hostgroup *this_hostgroup) {
7499 	hostgroup *new_hostgroup = NULL;
7500 
7501 	/* bail out if we shouldn't register this object */
7502 	if(this_hostgroup->register_object == FALSE)
7503 		return OK;
7504 
7505 	/* add the  host group */
7506 	new_hostgroup = add_hostgroup(this_hostgroup->hostgroup_name, this_hostgroup->alias, this_hostgroup->notes, this_hostgroup->notes_url, this_hostgroup->action_url);
7507 
7508 	/* return with an error if we couldn't add the hostgroup */
7509 	if(new_hostgroup == NULL) {
7510 		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);
7511 		return ERROR;
7512 		}
7513 
7514 	return OK;
7515 	}
7516 
7517 /* registers a servicegroup definition */
xodtemplate_register_servicegroup(xodtemplate_servicegroup * this_servicegroup)7518 int xodtemplate_register_servicegroup(xodtemplate_servicegroup *this_servicegroup) {
7519 	servicegroup *new_servicegroup = NULL;
7520 
7521 	/* bail out if we shouldn't register this object */
7522 	if(this_servicegroup->register_object == FALSE)
7523 		return OK;
7524 
7525 	/* add the  service group */
7526 	new_servicegroup = add_servicegroup(this_servicegroup->servicegroup_name, this_servicegroup->alias, this_servicegroup->notes, this_servicegroup->notes_url, this_servicegroup->action_url);
7527 
7528 	/* return with an error if we couldn't add the servicegroup */
7529 	if(new_servicegroup == NULL) {
7530 		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);
7531 		return ERROR;
7532 		}
7533 
7534 	return OK;
7535 	}
7536 
7537 
7538 /* registers a servicedependency definition */
xodtemplate_register_servicedependency(xodtemplate_servicedependency * this_servicedependency)7539 int xodtemplate_register_servicedependency(xodtemplate_servicedependency *this_servicedependency) {
7540 	servicedependency *new_servicedependency = NULL;
7541 
7542 	/* bail out if we shouldn't register this object */
7543 	if(this_servicedependency->register_object == FALSE)
7544 		return OK;
7545 
7546 	/* throw a warning on servicedeps that have no options */
7547 	if(this_servicedependency->have_notification_failure_options == FALSE && this_servicedependency->have_execution_failure_options == FALSE) {
7548 		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);
7549 		return OK;
7550 		}
7551 
7552 	/* add the servicedependency */
7553 	if(this_servicedependency->have_execution_failure_options == TRUE) {
7554 		xodcount.servicedependencies++;
7555 
7556 		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->execution_failure_options, this_servicedependency->dependency_period);
7557 
7558 		/* return with an error if we couldn't add the servicedependency */
7559 		if(new_servicedependency == NULL) {
7560 			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);
7561 			return ERROR;
7562 			}
7563 		}
7564 	if(this_servicedependency->have_notification_failure_options == TRUE) {
7565 		xodcount.servicedependencies++;
7566 
7567 		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->notification_failure_options, this_servicedependency->dependency_period);
7568 
7569 		/* return with an error if we couldn't add the servicedependency */
7570 		if(new_servicedependency == NULL) {
7571 			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);
7572 			return ERROR;
7573 			}
7574 		}
7575 
7576 	return OK;
7577 	}
7578 
7579 
7580 
7581 /* registers a serviceescalation definition */
xodtemplate_register_serviceescalation(xodtemplate_serviceescalation * this_serviceescalation)7582 int xodtemplate_register_serviceescalation(xodtemplate_serviceescalation *this_serviceescalation) {
7583 	serviceescalation *new_serviceescalation = NULL;
7584 	contactsmember *new_contactsmember = NULL;
7585 	contactgroupsmember *new_contactgroupsmember = NULL;
7586 	char *contact_name = NULL;
7587 	char *contact_group = NULL;
7588 
7589 	/* bail out if we shouldn't register this object */
7590 	if(this_serviceescalation->register_object == FALSE)
7591 		return OK;
7592 
7593 	/* default options if none specified */
7594 	if(this_serviceescalation->have_escalation_options == FALSE) {
7595 		this_serviceescalation->escalation_options = OPT_ALL;
7596 		}
7597 
7598 	/* add the serviceescalation */
7599 	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->escalation_options);
7600 
7601 	/* return with an error if we couldn't add the serviceescalation */
7602 	if(new_serviceescalation == NULL) {
7603 		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);
7604 		return ERROR;
7605 		}
7606 
7607 	/* add all contact groups to the serviceescalation */
7608 	if(this_serviceescalation->contact_groups != NULL) {
7609 
7610 		contactgroupsmember *temp_contact_group = NULL;
7611 
7612 		for(contact_group = strtok(this_serviceescalation->contact_groups, ","); contact_group != NULL; contact_group = strtok(NULL, ",")) {
7613 
7614 			int found_match = FALSE;
7615 
7616 			strip(contact_group);
7617 
7618 			/* unless this contact group already exists on the serviceescalation */
7619 			if (new_serviceescalation->contact_groups != NULL) {
7620 				for(temp_contact_group = new_serviceescalation->contact_groups; temp_contact_group != NULL; temp_contact_group = temp_contact_group->next) {
7621 					if (!strcmp(temp_contact_group->group_name, contact_group)) {
7622 						found_match = TRUE;
7623 						break;
7624 						}
7625 					}
7626 				}
7627 
7628 			if (found_match == FALSE) {
7629 				new_contactgroupsmember = add_contactgroup_to_serviceescalation(new_serviceescalation, contact_group);
7630 				if(new_contactgroupsmember == NULL) {
7631 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contactgroup '%s' to serviceescalation (config file '%s', starting on line %d)\n", contact_group, xodtemplate_config_file_name(this_serviceescalation->_config_file), this_serviceescalation->_start_line);
7632 					return ERROR;
7633 					}
7634 				}
7635 			}
7636 		}
7637 
7638 	/* add all contacts to the serviceescalation */
7639 	if(this_serviceescalation->contacts != NULL) {
7640 
7641 		contactsmember *temp_contact = NULL;
7642 
7643 		for(contact_name = strtok(this_serviceescalation->contacts, ","); contact_name != NULL; contact_name = strtok(NULL, ",")) {
7644 
7645 			int found_match = FALSE;
7646 
7647 			strip(contact_name);
7648 
7649 			/* unless this contact already exists on the serviceescalation */
7650 			if (new_serviceescalation->contacts != NULL) {
7651 				for(temp_contact = new_serviceescalation->contacts; temp_contact != NULL; temp_contact = temp_contact->next) {
7652 					if (!strcmp(temp_contact->contact_name, contact_name)) {
7653 						found_match = TRUE;
7654 						break;
7655 						}
7656 					}
7657 				}
7658 
7659 			if (found_match == FALSE) {
7660 				new_contactsmember = add_contact_to_serviceescalation(new_serviceescalation, contact_name);
7661 				if(new_contactsmember == NULL) {
7662 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contact '%s' to serviceescalation (config file '%s', starting on line %d)\n", contact_name, xodtemplate_config_file_name(this_serviceescalation->_config_file), this_serviceescalation->_start_line);
7663 					return ERROR;
7664 					}
7665 				}
7666 			}
7667 		}
7668 
7669 	return OK;
7670 	}
7671 
7672 
7673 
7674 /* registers a contact definition */
xodtemplate_register_contact(xodtemplate_contact * this_contact)7675 int xodtemplate_register_contact(xodtemplate_contact *this_contact) {
7676 	contact *new_contact = NULL;
7677 	char *command_name = NULL;
7678 	commandsmember *new_commandsmember = NULL;
7679 	xodtemplate_customvariablesmember *temp_customvariablesmember = NULL;
7680 
7681 	/* bail out if we shouldn't register this object */
7682 	if(this_contact->register_object == FALSE)
7683 		return OK;
7684 
7685 	/* add the contact */
7686 	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->service_notification_options, this_contact->host_notification_options, 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, this_contact->minimum_value);
7687 
7688 	/* return with an error if we couldn't add the contact */
7689 	if(new_contact == NULL) {
7690 		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);
7691 		return ERROR;
7692 		}
7693 
7694 	/* add all the host notification commands */
7695 	if(this_contact->host_notification_commands != NULL) {
7696 
7697 		for(command_name = strtok(this_contact->host_notification_commands, ", "); command_name != NULL; command_name = strtok(NULL, ", ")) {
7698 			new_commandsmember = add_host_notification_command_to_contact(new_contact, command_name);
7699 			if(new_commandsmember == NULL) {
7700 				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);
7701 				return ERROR;
7702 				}
7703 			}
7704 		}
7705 
7706 	/* add all the service notification commands */
7707 	if(this_contact->service_notification_commands != NULL) {
7708 
7709 		for(command_name = strtok(this_contact->service_notification_commands, ", "); command_name != NULL; command_name = strtok(NULL, ", ")) {
7710 			new_commandsmember = add_service_notification_command_to_contact(new_contact, command_name);
7711 			if(new_commandsmember == NULL) {
7712 				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);
7713 				return ERROR;
7714 				}
7715 			}
7716 		}
7717 
7718 	/* add all custom variables */
7719 	for(temp_customvariablesmember = this_contact->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) {
7720 		if((add_custom_variable_to_contact(new_contact, temp_customvariablesmember->variable_name, temp_customvariablesmember->variable_value)) == NULL) {
7721 			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);
7722 			return ERROR;
7723 			}
7724 		}
7725 
7726 	return OK;
7727 	}
7728 
7729 
7730 
7731 /* registers a host definition */
xodtemplate_register_host(xodtemplate_host * this_host)7732 int xodtemplate_register_host(xodtemplate_host *this_host) {
7733 	host *new_host = NULL;
7734 	char *parent_host = NULL;
7735 	hostsmember *new_hostsmember = NULL;
7736 	contactsmember *new_contactsmember = NULL;
7737 	contactgroupsmember *new_contactgroupsmember = NULL;
7738 	char *contact_name = NULL;
7739 	char *contact_group = NULL;
7740 	xodtemplate_customvariablesmember *temp_customvariablesmember = NULL;
7741 
7742 	/* bail out if we shouldn't register this object */
7743 	if(this_host->register_object == FALSE)
7744 		return OK;
7745 
7746 	/* add the host definition */
7747 	new_host = add_host(this_host->host_name, this_host->display_name, this_host->alias, 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->notification_options, 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_options, this_host->stalking_options, this_host->process_perf_data, 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, this_host->hourly_value);
7748 
7749 
7750 	/* return with an error if we couldn't add the host */
7751 	if(new_host == NULL) {
7752 		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);
7753 		return ERROR;
7754 		}
7755 
7756 	/* add the parent hosts */
7757 	if(this_host->parents != NULL) {
7758 
7759 		for(parent_host = strtok(this_host->parents, ","); parent_host != NULL; parent_host = strtok(NULL, ",")) {
7760 			strip(parent_host);
7761 			new_hostsmember = add_parent_host_to_host(new_host, parent_host);
7762 			if(new_hostsmember == NULL) {
7763 				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);
7764 				return ERROR;
7765 				}
7766 			}
7767 		}
7768 
7769 	/* add all contact groups to the host */
7770 	if(this_host->contact_groups != NULL) {
7771 
7772 		contactgroupsmember *temp_contact_group = NULL;
7773 
7774 		for(contact_group = strtok(this_host->contact_groups, ","); contact_group != NULL; contact_group = strtok(NULL, ",")) {
7775 
7776 			int found_match = FALSE;
7777 
7778 			strip(contact_group);
7779 
7780 			/* unless this contact group already exists on the host */
7781 			if (new_host->contact_groups != NULL) {
7782 				for(temp_contact_group = new_host->contact_groups; temp_contact_group != NULL; temp_contact_group = temp_contact_group->next) {
7783 					if (!strcmp(temp_contact_group->group_name, contact_group)) {
7784 						found_match = TRUE;
7785 						break;
7786 						}
7787 					}
7788 				}
7789 
7790 			if (found_match == FALSE) {
7791 				new_contactgroupsmember = add_contactgroup_to_host(new_host, contact_group);
7792 				if(new_contactgroupsmember == NULL) {
7793 					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);
7794 					return ERROR;
7795 					}
7796 				}
7797 			}
7798 		}
7799 
7800 	/* add all contacts to the host */
7801 	if(this_host->contacts != NULL) {
7802 
7803 		contactsmember *temp_contact = NULL;
7804 
7805 		for(contact_name = strtok(this_host->contacts, ","); contact_name != NULL; contact_name = strtok(NULL, ",")) {
7806 
7807 			int found_match = FALSE;
7808 
7809 			strip(contact_name);
7810 
7811 			/* unless this contact already exists on the host */
7812 			if (new_host->contacts != NULL) {
7813 				for(temp_contact = new_host->contacts; temp_contact != NULL; temp_contact = temp_contact->next) {
7814 					if (!strcmp(temp_contact->contact_name, contact_name)) {
7815 						found_match = TRUE;
7816 						break;
7817 						}
7818 					}
7819 				}
7820 
7821 			if (found_match == FALSE) {
7822 				new_contactsmember = add_contact_to_host(new_host, contact_name);
7823 				if(new_contactsmember == NULL) {
7824 					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);
7825 					return ERROR;
7826 					}
7827 				}
7828 			}
7829 		}
7830 
7831 	/* add all custom variables */
7832 	for(temp_customvariablesmember = this_host->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) {
7833 		if((add_custom_variable_to_host(new_host, temp_customvariablesmember->variable_name, temp_customvariablesmember->variable_value)) == NULL) {
7834 			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);
7835 			return ERROR;
7836 			}
7837 		}
7838 
7839 	return OK;
7840 	}
7841 
7842 
7843 
7844 /* registers a service definition */
xodtemplate_register_service(xodtemplate_service * this_service)7845 int xodtemplate_register_service(xodtemplate_service *this_service) {
7846 	service *new_service = NULL;
7847 	contactsmember *new_contactsmember = NULL;
7848 	contactgroupsmember *new_contactgroupsmember = NULL;
7849 	char *contact_name = NULL;
7850 	char *contact_group = NULL;
7851 	xodtemplate_customvariablesmember *temp_customvariablesmember = NULL;
7852 
7853 	/* bail out if we shouldn't register this object */
7854 	if(this_service->register_object == FALSE)
7855 		return OK;
7856 
7857 	/* add the service */
7858 	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->notification_options, 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_options, this_service->stalking_options, this_service->process_perf_data, 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, this_service->hourly_value);
7859 
7860 	/* return with an error if we couldn't add the service */
7861 	if(new_service == NULL) {
7862 		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);
7863 		return ERROR;
7864 		}
7865 
7866 	/* add all service parents */
7867 	if(this_service->parents != NULL) {
7868 		servicesmember *new_servicesmember;
7869 		char *comma = strchr(this_service->parents, ',');
7870 
7871 		if(!comma) { /* same-host single-service parent */
7872 			new_servicesmember = add_parent_service_to_service(new_service, new_service->host_name, this_service->parents);
7873 			if(new_servicesmember == NULL) {
7874 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add same-host service parent '%s' to service (config file '%s', starting on line %d)\n",
7875 					  this_service->parents,
7876 					  xodtemplate_config_file_name(this_service->_config_file),
7877 					  this_service->_start_line);
7878 				return ERROR;
7879 				}
7880 			}
7881 		else {
7882 			/* Multiple parents, so let's do this the hard way */
7883 			objectlist *list = NULL, *next;
7884 			bitmap_clear(service_map);
7885 			if(xodtemplate_expand_services(&list, service_map, NULL, this_service->parents, this_service->_config_file, this_service->_start_line) != OK) {
7886 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Failed to expand service parents (config file '%s', starting at line %d)\n",
7887 					  xodtemplate_config_file_name(this_service->_config_file),
7888 					  this_service->_start_line);
7889 				return ERROR;
7890 				}
7891 			for(; list; list = next) {
7892 				xodtemplate_service *parent = (xodtemplate_service *)list->object_ptr;
7893 				next = list->next;
7894 				free(list);
7895 				new_servicesmember = add_parent_service_to_service(new_service, parent->host_name, parent->service_description);
7896 				if(new_servicesmember == NULL) {
7897 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add service '%s' on host '%s' as parent to service '%s' on host '%s' (config file '%s', starting on line %d)\n",
7898 						  parent->host_name, parent->service_description,
7899 						  new_service->host_name, new_service->description,
7900 						  xodtemplate_config_file_name(this_service->_config_file),
7901 						  this_service->_start_line);
7902 					free_objectlist(&next);
7903 					return ERROR;
7904 					}
7905 				}
7906 			}
7907 		}
7908 
7909 	/* add all contact groups to the service */
7910 	if(this_service->contact_groups != NULL) {
7911 
7912 		contactgroupsmember *temp_contact_group = NULL;
7913 
7914 		for(contact_group = strtok(this_service->contact_groups, ","); contact_group != NULL; contact_group = strtok(NULL, ",")) {
7915 
7916 			int found_match = FALSE;
7917 
7918 			strip(contact_group);
7919 
7920 			/* unless this contact group already exists on the service */
7921 			if (new_service->contact_groups != NULL) {
7922 				for(temp_contact_group = new_service->contact_groups; temp_contact_group != NULL; temp_contact_group = temp_contact_group->next) {
7923 					if (!strcmp(temp_contact_group->group_name, contact_group)) {
7924 						found_match = TRUE;
7925 						break;
7926 						}
7927 					}
7928 				}
7929 
7930 			if (found_match == FALSE) {
7931 				new_contactgroupsmember = add_contactgroup_to_service(new_service, contact_group);
7932 				if(new_contactgroupsmember == NULL) {
7933 					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);
7934 					return ERROR;
7935 					}
7936 				}
7937 			}
7938 		}
7939 
7940 	/* add all contacts to the service */
7941 	if(this_service->contacts != NULL) {
7942 
7943 		contactsmember *temp_contact = NULL;
7944 
7945 		for(contact_name = strtok(this_service->contacts, ","); contact_name != NULL; contact_name = strtok(NULL, ",")) {
7946 
7947 			int found_match = FALSE;
7948 
7949 			strip(contact_name);
7950 
7951 			/* unless this contact already exists on the service */
7952 			if (new_service->contacts != NULL) {
7953 				for(temp_contact = new_service->contacts; temp_contact != NULL; temp_contact = temp_contact->next) {
7954 					if (!strcmp(temp_contact->contact_name, contact_name)) {
7955 						found_match = TRUE;
7956 						break;
7957 						}
7958 					}
7959 				}
7960 
7961 			if (found_match == FALSE) {
7962 				new_contactsmember = add_contact_to_service(new_service, contact_name);
7963 				if(new_contactsmember == NULL) {
7964 					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);
7965 					return ERROR;
7966 					}
7967 				}
7968 			}
7969 		}
7970 
7971 	/* add all custom variables */
7972 	for(temp_customvariablesmember = this_service->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) {
7973 		if((add_custom_variable_to_service(new_service, temp_customvariablesmember->variable_name, temp_customvariablesmember->variable_value)) == NULL) {
7974 			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);
7975 			return ERROR;
7976 			}
7977 		}
7978 
7979 	return OK;
7980 	}
7981 
7982 
7983 
7984 /* registers a hostdependency definition */
xodtemplate_register_hostdependency(xodtemplate_hostdependency * this_hostdependency)7985 int xodtemplate_register_hostdependency(xodtemplate_hostdependency *this_hostdependency) {
7986 	hostdependency *new_hostdependency = NULL;
7987 
7988 	/* bail out if we shouldn't register this object */
7989 	if(this_hostdependency->register_object == FALSE)
7990 		return OK;
7991 
7992 	/* add the host execution dependency */
7993 	if(this_hostdependency->have_execution_failure_options == TRUE) {
7994 		xodcount.hostdependencies++;
7995 
7996 		new_hostdependency = add_host_dependency(this_hostdependency->dependent_host_name, this_hostdependency->host_name, EXECUTION_DEPENDENCY, this_hostdependency->inherits_parent, this_hostdependency->execution_failure_options, this_hostdependency->dependency_period);
7997 
7998 		/* return with an error if we couldn't add the hostdependency */
7999 		if(new_hostdependency == NULL) {
8000 			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);
8001 			return ERROR;
8002 			}
8003 		}
8004 
8005 	/* add the host notification dependency */
8006 	if(this_hostdependency->have_notification_failure_options == TRUE) {
8007 		xodcount.hostdependencies++;
8008 
8009 		new_hostdependency = add_host_dependency(this_hostdependency->dependent_host_name, this_hostdependency->host_name, NOTIFICATION_DEPENDENCY, this_hostdependency->inherits_parent, this_hostdependency->notification_failure_options, this_hostdependency->dependency_period);
8010 
8011 		/* return with an error if we couldn't add the hostdependency */
8012 		if(new_hostdependency == NULL) {
8013 			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);
8014 			return ERROR;
8015 			}
8016 		}
8017 
8018 	return OK;
8019 	}
8020 
8021 
8022 
8023 /* registers a hostescalation definition */
xodtemplate_register_hostescalation(xodtemplate_hostescalation * this_hostescalation)8024 int xodtemplate_register_hostescalation(xodtemplate_hostescalation *this_hostescalation) {
8025 	hostescalation *new_hostescalation = NULL;
8026 	contactsmember *new_contactsmember = NULL;
8027 	contactgroupsmember *new_contactgroupsmember = NULL;
8028 	char *contact_name = NULL;
8029 	char *contact_group = NULL;
8030 
8031 	/* bail out if we shouldn't register this object */
8032 	if(this_hostescalation->register_object == FALSE)
8033 		return OK;
8034 
8035 	/* default options if none specified */
8036 	if(this_hostescalation->have_escalation_options == FALSE) {
8037 		this_hostescalation->escalation_options = OPT_ALL;
8038 		}
8039 
8040 	/* add the hostescalation */
8041 	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->escalation_options);
8042 
8043 	/* return with an error if we couldn't add the hostescalation */
8044 	if(new_hostescalation == NULL) {
8045 		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);
8046 		return ERROR;
8047 		}
8048 
8049 	/* add all contact groups to the hostescalation */
8050 	if(this_hostescalation->contact_groups != NULL) {
8051 
8052 		contactgroupsmember *temp_contact_group = NULL;
8053 
8054 		for(contact_group = strtok(this_hostescalation->contact_groups, ","); contact_group != NULL; contact_group = strtok(NULL, ",")) {
8055 
8056 			int found_match = FALSE;
8057 
8058 			strip(contact_group);
8059 
8060 			/* unless this contact group already exists on the hostescalation */
8061 			if (new_hostescalation->contact_groups != NULL) {
8062 				for(temp_contact_group = new_hostescalation->contact_groups; temp_contact_group != NULL; temp_contact_group = temp_contact_group->next) {
8063 					if (!strcmp(temp_contact_group->group_name, contact_group)) {
8064 						found_match = TRUE;
8065 						break;
8066 						}
8067 					}
8068 				}
8069 
8070 			if (found_match == FALSE) {
8071 				new_contactgroupsmember = add_contactgroup_to_hostescalation(new_hostescalation, contact_group);
8072 				if(new_contactgroupsmember == NULL) {
8073 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contactgroup '%s' to hostescalation (config file '%s', starting on line %d)\n", contact_group, xodtemplate_config_file_name(this_hostescalation->_config_file), this_hostescalation->_start_line);
8074 					return ERROR;
8075 					}
8076 				}
8077 			}
8078 		}
8079 
8080 	/* add all contacts to the hostescalation */
8081 	if(this_hostescalation->contacts != NULL) {
8082 
8083 		contactsmember *temp_contact = NULL;
8084 
8085 		for(contact_name = strtok(this_hostescalation->contacts, ","); contact_name != NULL; contact_name = strtok(NULL, ",")) {
8086 
8087 			int found_match = FALSE;
8088 
8089 			strip(contact_name);
8090 
8091 			/* unless this contact already exists on the hostescalation */
8092 			if (new_hostescalation->contacts != NULL) {
8093 				for(temp_contact = new_hostescalation->contacts; temp_contact != NULL; temp_contact = temp_contact->next) {
8094 					if (!strcmp(temp_contact->contact_name, contact_name)) {
8095 						found_match = TRUE;
8096 						break;
8097 						}
8098 					}
8099 				}
8100 
8101 			if (found_match == FALSE) {
8102 				new_contactsmember = add_contact_to_hostescalation(new_hostescalation, contact_name);
8103 				if(new_contactsmember == NULL) {
8104 					logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contact '%s' to hostescalation (config file '%s', starting on line %d)\n", contact_name, xodtemplate_config_file_name(this_hostescalation->_config_file), this_hostescalation->_start_line);
8105 					return ERROR;
8106 					}
8107 				}
8108 			}
8109 		}
8110 
8111 	return OK;
8112 	}
8113 
8114 
8115 
8116 
8117 /******************************************************************/
8118 /*********************** MERGE FUNCTIONS **************************/
8119 /******************************************************************/
8120 
8121 #ifdef NSCORE
8122 
8123 /* merges a service extinfo definition */
xodtemplate_merge_service_extinfo_object(xodtemplate_service * this_service,xodtemplate_serviceextinfo * this_serviceextinfo)8124 int xodtemplate_merge_service_extinfo_object(xodtemplate_service *this_service, xodtemplate_serviceextinfo *this_serviceextinfo) {
8125 
8126 	if(this_service == NULL || this_serviceextinfo == NULL)
8127 		return ERROR;
8128 
8129 	if(this_service->notes == NULL && this_serviceextinfo->notes != NULL)
8130 		this_service->notes = strdup(this_serviceextinfo->notes);
8131 	if(this_service->notes_url == NULL && this_serviceextinfo->notes_url != NULL)
8132 		this_service->notes_url = strdup(this_serviceextinfo->notes_url);
8133 	if(this_service->action_url == NULL && this_serviceextinfo->action_url != NULL)
8134 		this_service->action_url = strdup(this_serviceextinfo->action_url);
8135 	if(this_service->icon_image == NULL && this_serviceextinfo->icon_image != NULL)
8136 		this_service->icon_image = strdup(this_serviceextinfo->icon_image);
8137 	if(this_service->icon_image_alt == NULL && this_serviceextinfo->icon_image_alt != NULL)
8138 		this_service->icon_image_alt = strdup(this_serviceextinfo->icon_image_alt);
8139 
8140 	return OK;
8141 	}
8142 
8143 
8144 /* merges a host extinfo definition */
xodtemplate_merge_host_extinfo_object(xodtemplate_host * this_host,xodtemplate_hostextinfo * this_hostextinfo)8145 int xodtemplate_merge_host_extinfo_object(xodtemplate_host *this_host, xodtemplate_hostextinfo *this_hostextinfo) {
8146 
8147 	if(this_host == NULL || this_hostextinfo == NULL)
8148 		return ERROR;
8149 
8150 	if(this_host->notes == NULL && this_hostextinfo->notes != NULL)
8151 		this_host->notes = strdup(this_hostextinfo->notes);
8152 	if(this_host->notes_url == NULL && this_hostextinfo->notes_url != NULL)
8153 		this_host->notes_url = strdup(this_hostextinfo->notes_url);
8154 	if(this_host->action_url == NULL && this_hostextinfo->action_url != NULL)
8155 		this_host->action_url = strdup(this_hostextinfo->action_url);
8156 	if(this_host->icon_image == NULL && this_hostextinfo->icon_image != NULL)
8157 		this_host->icon_image = strdup(this_hostextinfo->icon_image);
8158 	if(this_host->icon_image_alt == NULL && this_hostextinfo->icon_image_alt != NULL)
8159 		this_host->icon_image_alt = strdup(this_hostextinfo->icon_image_alt);
8160 	if(this_host->vrml_image == NULL && this_hostextinfo->vrml_image != NULL)
8161 		this_host->vrml_image = strdup(this_hostextinfo->vrml_image);
8162 	if(this_host->statusmap_image == NULL && this_hostextinfo->statusmap_image != NULL)
8163 		this_host->statusmap_image = strdup(this_hostextinfo->statusmap_image);
8164 
8165 	if(this_host->have_2d_coords == FALSE && this_hostextinfo->have_2d_coords == TRUE) {
8166 		this_host->x_2d = this_hostextinfo->x_2d;
8167 		this_host->y_2d = this_hostextinfo->y_2d;
8168 		this_host->have_2d_coords = TRUE;
8169 		}
8170 	if(this_host->have_3d_coords == FALSE && this_hostextinfo->have_3d_coords == TRUE) {
8171 		this_host->x_3d = this_hostextinfo->x_3d;
8172 		this_host->y_3d = this_hostextinfo->y_3d;
8173 		this_host->z_3d = this_hostextinfo->z_3d;
8174 		this_host->have_3d_coords = TRUE;
8175 		}
8176 
8177 	return OK;
8178 	}
8179 
8180 #endif
8181 
8182 
8183 /******************************************************************/
8184 /******************** SKIPLIST FUNCTIONS **************************/
8185 /******************************************************************/
8186 
xodtemplate_init_xobject_skiplists(void)8187 int xodtemplate_init_xobject_skiplists(void) {
8188 	int x = 0;
8189 
8190 	for(x = 0; x < NUM_XOBJECT_SKIPLISTS; x++) {
8191 		xobject_template_skiplists[x] = NULL;
8192 		xobject_skiplists[x] = NULL;
8193 		}
8194 
8195 	xobject_template_skiplists[HOST_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_host_template);
8196 	xobject_template_skiplists[SERVICE_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_service_template);
8197 	xobject_template_skiplists[COMMAND_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_command_template);
8198 	xobject_template_skiplists[TIMEPERIOD_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_timeperiod_template);
8199 	xobject_template_skiplists[CONTACT_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_contact_template);
8200 	xobject_template_skiplists[CONTACTGROUP_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_contactgroup_template);
8201 	xobject_template_skiplists[HOSTGROUP_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_hostgroup_template);
8202 	xobject_template_skiplists[SERVICEGROUP_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_servicegroup_template);
8203 	xobject_template_skiplists[HOSTDEPENDENCY_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_hostdependency_template);
8204 	xobject_template_skiplists[SERVICEDEPENDENCY_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_servicedependency_template);
8205 	xobject_template_skiplists[HOSTESCALATION_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_hostescalation_template);
8206 	xobject_template_skiplists[SERVICEESCALATION_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_serviceescalation_template);
8207 	xobject_template_skiplists[HOSTEXTINFO_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_hostextinfo_template);
8208 	xobject_template_skiplists[SERVICEEXTINFO_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_serviceextinfo_template);
8209 
8210 	xobject_skiplists[HOST_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_host);
8211 	xobject_skiplists[SERVICE_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_service);
8212 	xobject_skiplists[COMMAND_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_command);
8213 	xobject_skiplists[TIMEPERIOD_SKIPLIST] = skiplist_new(16, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_timeperiod);
8214 	xobject_skiplists[CONTACT_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_contact);
8215 	xobject_skiplists[CONTACTGROUP_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_contactgroup);
8216 	xobject_skiplists[HOSTGROUP_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_hostgroup);
8217 	xobject_skiplists[SERVICEGROUP_SKIPLIST] = skiplist_new(10, 0.5, FALSE, FALSE, xodtemplate_skiplist_compare_servicegroup);
8218 	/*
8219 	 * host and service extinfo, dependencies, and escalations don't
8220 	 * need to be sorted, so we avoid creating skiplists for them.
8221 	 */
8222 	return OK;
8223 	}
8224 
8225 
8226 
xodtemplate_free_xobject_skiplists(void)8227 int xodtemplate_free_xobject_skiplists(void) {
8228 	int x = 0;
8229 
8230 	for(x = 0; x < NUM_XOBJECT_SKIPLISTS; x++) {
8231 		skiplist_free(&xobject_template_skiplists[x]);
8232 		skiplist_free(&xobject_skiplists[x]);
8233 		}
8234 
8235 	return OK;
8236 	}
8237 
8238 
xodtemplate_skiplist_compare_host_template(void * a,void * b)8239 int xodtemplate_skiplist_compare_host_template(void *a, void *b) {
8240 	xodtemplate_host *oa = NULL;
8241 	xodtemplate_host *ob = NULL;
8242 
8243 	oa = (xodtemplate_host *)a;
8244 	ob = (xodtemplate_host *)b;
8245 
8246 	if(oa == NULL && ob == NULL)
8247 		return 0;
8248 	if(oa == NULL)
8249 		return 1;
8250 	if(ob == NULL)
8251 		return -1;
8252 
8253 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
8254 	}
8255 
8256 
8257 
xodtemplate_skiplist_compare_host(void * a,void * b)8258 int xodtemplate_skiplist_compare_host(void *a, void *b) {
8259 	xodtemplate_host *oa = NULL;
8260 	xodtemplate_host *ob = NULL;
8261 
8262 	oa = (xodtemplate_host *)a;
8263 	ob = (xodtemplate_host *)b;
8264 
8265 	if(oa == NULL && ob == NULL)
8266 		return 0;
8267 	if(oa == NULL)
8268 		return 1;
8269 	if(ob == NULL)
8270 		return -1;
8271 
8272 	return skiplist_compare_text(oa->host_name, NULL, ob->host_name, NULL);
8273 	}
8274 
8275 
8276 
xodtemplate_skiplist_compare_service_template(void * a,void * b)8277 int xodtemplate_skiplist_compare_service_template(void *a, void *b) {
8278 	xodtemplate_service *oa = NULL;
8279 	xodtemplate_service *ob = NULL;
8280 
8281 	oa = (xodtemplate_service *)a;
8282 	ob = (xodtemplate_service *)b;
8283 
8284 	if(oa == NULL && ob == NULL)
8285 		return 0;
8286 	if(oa == NULL)
8287 		return 1;
8288 	if(ob == NULL)
8289 		return -1;
8290 
8291 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
8292 	}
8293 
8294 
8295 
xodtemplate_skiplist_compare_service(void * a,void * b)8296 int xodtemplate_skiplist_compare_service(void *a, void *b) {
8297 	xodtemplate_service *oa = NULL;
8298 	xodtemplate_service *ob = NULL;
8299 
8300 	oa = (xodtemplate_service *)a;
8301 	ob = (xodtemplate_service *)b;
8302 
8303 	if(oa == NULL && ob == NULL)
8304 		return 0;
8305 	if(oa == NULL)
8306 		return 1;
8307 	if(ob == NULL)
8308 		return -1;
8309 
8310 	return skiplist_compare_text(oa->host_name, oa->service_description, ob->host_name, ob->service_description);
8311 	}
8312 
8313 
8314 
xodtemplate_skiplist_compare_timeperiod_template(void * a,void * b)8315 int xodtemplate_skiplist_compare_timeperiod_template(void *a, void *b) {
8316 	xodtemplate_timeperiod *oa = NULL;
8317 	xodtemplate_timeperiod *ob = NULL;
8318 
8319 	oa = (xodtemplate_timeperiod *)a;
8320 	ob = (xodtemplate_timeperiod *)b;
8321 
8322 	if(oa == NULL && ob == NULL)
8323 		return 0;
8324 	if(oa == NULL)
8325 		return 1;
8326 	if(ob == NULL)
8327 		return -1;
8328 
8329 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
8330 	}
8331 
8332 
8333 
xodtemplate_skiplist_compare_timeperiod(void * a,void * b)8334 int xodtemplate_skiplist_compare_timeperiod(void *a, void *b) {
8335 	xodtemplate_timeperiod *oa = NULL;
8336 	xodtemplate_timeperiod *ob = NULL;
8337 
8338 	oa = (xodtemplate_timeperiod *)a;
8339 	ob = (xodtemplate_timeperiod *)b;
8340 
8341 	if(oa == NULL && ob == NULL)
8342 		return 0;
8343 	if(oa == NULL)
8344 		return 1;
8345 	if(ob == NULL)
8346 		return -1;
8347 
8348 	return skiplist_compare_text(oa->timeperiod_name, NULL, ob->timeperiod_name, NULL);
8349 	}
8350 
8351 
8352 
xodtemplate_skiplist_compare_command_template(void * a,void * b)8353 int xodtemplate_skiplist_compare_command_template(void *a, void *b) {
8354 	xodtemplate_command *oa = NULL;
8355 	xodtemplate_command *ob = NULL;
8356 
8357 	oa = (xodtemplate_command *)a;
8358 	ob = (xodtemplate_command *)b;
8359 
8360 	if(oa == NULL && ob == NULL)
8361 		return 0;
8362 	if(oa == NULL)
8363 		return 1;
8364 	if(ob == NULL)
8365 		return -1;
8366 
8367 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
8368 	}
8369 
8370 
8371 
xodtemplate_skiplist_compare_command(void * a,void * b)8372 int xodtemplate_skiplist_compare_command(void *a, void *b) {
8373 	xodtemplate_command *oa = NULL;
8374 	xodtemplate_command *ob = NULL;
8375 
8376 	oa = (xodtemplate_command *)a;
8377 	ob = (xodtemplate_command *)b;
8378 
8379 	if(oa == NULL && ob == NULL)
8380 		return 0;
8381 	if(oa == NULL)
8382 		return 1;
8383 	if(ob == NULL)
8384 		return -1;
8385 
8386 	return skiplist_compare_text(oa->command_name, NULL, ob->command_name, NULL);
8387 	}
8388 
8389 
8390 
xodtemplate_skiplist_compare_contact_template(void * a,void * b)8391 int xodtemplate_skiplist_compare_contact_template(void *a, void *b) {
8392 	xodtemplate_contact *oa = NULL;
8393 	xodtemplate_contact *ob = NULL;
8394 
8395 	oa = (xodtemplate_contact *)a;
8396 	ob = (xodtemplate_contact *)b;
8397 
8398 	if(oa == NULL && ob == NULL)
8399 		return 0;
8400 	if(oa == NULL)
8401 		return 1;
8402 	if(ob == NULL)
8403 		return -1;
8404 
8405 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
8406 	}
8407 
8408 
8409 
xodtemplate_skiplist_compare_contact(void * a,void * b)8410 int xodtemplate_skiplist_compare_contact(void *a, void *b) {
8411 	xodtemplate_contact *oa = NULL;
8412 	xodtemplate_contact *ob = NULL;
8413 
8414 	oa = (xodtemplate_contact *)a;
8415 	ob = (xodtemplate_contact *)b;
8416 
8417 	if(oa == NULL && ob == NULL)
8418 		return 0;
8419 	if(oa == NULL)
8420 		return 1;
8421 	if(ob == NULL)
8422 		return -1;
8423 
8424 	return skiplist_compare_text(oa->contact_name, NULL, ob->contact_name, NULL);
8425 	}
8426 
8427 
8428 
xodtemplate_skiplist_compare_contactgroup_template(void * a,void * b)8429 int xodtemplate_skiplist_compare_contactgroup_template(void *a, void *b) {
8430 	xodtemplate_contactgroup *oa = NULL;
8431 	xodtemplate_contactgroup *ob = NULL;
8432 
8433 	oa = (xodtemplate_contactgroup *)a;
8434 	ob = (xodtemplate_contactgroup *)b;
8435 
8436 	if(oa == NULL && ob == NULL)
8437 		return 0;
8438 	if(oa == NULL)
8439 		return 1;
8440 	if(ob == NULL)
8441 		return -1;
8442 
8443 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
8444 	}
8445 
8446 
8447 
xodtemplate_skiplist_compare_contactgroup(void * a,void * b)8448 int xodtemplate_skiplist_compare_contactgroup(void *a, void *b) {
8449 	xodtemplate_contactgroup *oa = NULL;
8450 	xodtemplate_contactgroup *ob = NULL;
8451 
8452 	oa = (xodtemplate_contactgroup *)a;
8453 	ob = (xodtemplate_contactgroup *)b;
8454 
8455 	if(oa == NULL && ob == NULL)
8456 		return 0;
8457 	if(oa == NULL)
8458 		return 1;
8459 	if(ob == NULL)
8460 		return -1;
8461 
8462 	return skiplist_compare_text(oa->contactgroup_name, NULL, ob->contactgroup_name, NULL);
8463 	}
8464 
8465 
8466 
xodtemplate_skiplist_compare_hostgroup_template(void * a,void * b)8467 int xodtemplate_skiplist_compare_hostgroup_template(void *a, void *b) {
8468 	xodtemplate_hostgroup *oa = NULL;
8469 	xodtemplate_hostgroup *ob = NULL;
8470 
8471 	oa = (xodtemplate_hostgroup *)a;
8472 	ob = (xodtemplate_hostgroup *)b;
8473 
8474 	if(oa == NULL && ob == NULL)
8475 		return 0;
8476 	if(oa == NULL)
8477 		return 1;
8478 	if(ob == NULL)
8479 		return -1;
8480 
8481 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
8482 	}
8483 
8484 
8485 
xodtemplate_skiplist_compare_hostgroup(void * a,void * b)8486 int xodtemplate_skiplist_compare_hostgroup(void *a, void *b) {
8487 	xodtemplate_hostgroup *oa = NULL;
8488 	xodtemplate_hostgroup *ob = NULL;
8489 
8490 	oa = (xodtemplate_hostgroup *)a;
8491 	ob = (xodtemplate_hostgroup *)b;
8492 
8493 	if(oa == NULL && ob == NULL)
8494 		return 0;
8495 	if(oa == NULL)
8496 		return 1;
8497 	if(ob == NULL)
8498 		return -1;
8499 
8500 	return skiplist_compare_text(oa->hostgroup_name, NULL, ob->hostgroup_name, NULL);
8501 	}
8502 
8503 
8504 
xodtemplate_skiplist_compare_servicegroup_template(void * a,void * b)8505 int xodtemplate_skiplist_compare_servicegroup_template(void *a, void *b) {
8506 	xodtemplate_servicegroup *oa = NULL;
8507 	xodtemplate_servicegroup *ob = NULL;
8508 
8509 	oa = (xodtemplate_servicegroup *)a;
8510 	ob = (xodtemplate_servicegroup *)b;
8511 
8512 	if(oa == NULL && ob == NULL)
8513 		return 0;
8514 	if(oa == NULL)
8515 		return 1;
8516 	if(ob == NULL)
8517 		return -1;
8518 
8519 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
8520 	}
8521 
8522 
8523 
xodtemplate_skiplist_compare_servicegroup(void * a,void * b)8524 int xodtemplate_skiplist_compare_servicegroup(void *a, void *b) {
8525 	xodtemplate_servicegroup *oa = NULL;
8526 	xodtemplate_servicegroup *ob = NULL;
8527 
8528 	oa = (xodtemplate_servicegroup *)a;
8529 	ob = (xodtemplate_servicegroup *)b;
8530 
8531 	if(oa == NULL && ob == NULL)
8532 		return 0;
8533 	if(oa == NULL)
8534 		return 1;
8535 	if(ob == NULL)
8536 		return -1;
8537 
8538 	return skiplist_compare_text(oa->servicegroup_name, NULL, ob->servicegroup_name, NULL);
8539 	}
8540 
8541 
8542 
xodtemplate_skiplist_compare_hostdependency_template(void * a,void * b)8543 int xodtemplate_skiplist_compare_hostdependency_template(void *a, void *b) {
8544 	xodtemplate_hostdependency *oa = NULL;
8545 	xodtemplate_hostdependency *ob = NULL;
8546 
8547 	oa = (xodtemplate_hostdependency *)a;
8548 	ob = (xodtemplate_hostdependency *)b;
8549 
8550 	if(oa == NULL && ob == NULL)
8551 		return 0;
8552 	if(oa == NULL)
8553 		return 1;
8554 	if(ob == NULL)
8555 		return -1;
8556 
8557 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
8558 	}
8559 
8560 
8561 
xodtemplate_skiplist_compare_hostdependency(void * a,void * b)8562 int xodtemplate_skiplist_compare_hostdependency(void *a, void *b) {
8563 	xodtemplate_hostdependency *oa = NULL;
8564 	xodtemplate_hostdependency *ob = NULL;
8565 
8566 	oa = (xodtemplate_hostdependency *)a;
8567 	ob = (xodtemplate_hostdependency *)b;
8568 
8569 	if(oa == NULL && ob == NULL)
8570 		return 0;
8571 	if(oa == NULL)
8572 		return 1;
8573 	if(ob == NULL)
8574 		return -1;
8575 
8576 	return skiplist_compare_text(oa->dependent_host_name, NULL, ob->dependent_host_name, NULL);
8577 	}
8578 
8579 
8580 
xodtemplate_skiplist_compare_servicedependency_template(void * a,void * b)8581 int xodtemplate_skiplist_compare_servicedependency_template(void *a, void *b) {
8582 	xodtemplate_servicedependency *oa = NULL;
8583 	xodtemplate_servicedependency *ob = NULL;
8584 
8585 	oa = (xodtemplate_servicedependency *)a;
8586 	ob = (xodtemplate_servicedependency *)b;
8587 
8588 	if(oa == NULL && ob == NULL)
8589 		return 0;
8590 	if(oa == NULL)
8591 		return 1;
8592 	if(ob == NULL)
8593 		return -1;
8594 
8595 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
8596 	}
8597 
8598 
8599 
xodtemplate_skiplist_compare_servicedependency(void * a,void * b)8600 int xodtemplate_skiplist_compare_servicedependency(void *a, void *b) {
8601 	xodtemplate_servicedependency *oa = NULL;
8602 	xodtemplate_servicedependency *ob = NULL;
8603 
8604 	oa = (xodtemplate_servicedependency *)a;
8605 	ob = (xodtemplate_servicedependency *)b;
8606 
8607 	if(oa == NULL && ob == NULL)
8608 		return 0;
8609 	if(oa == NULL)
8610 		return 1;
8611 	if(ob == NULL)
8612 		return -1;
8613 
8614 	return skiplist_compare_text(oa->dependent_host_name, oa->dependent_service_description, ob->dependent_host_name, ob->dependent_service_description);
8615 	}
8616 
8617 
8618 
xodtemplate_skiplist_compare_hostescalation_template(void * a,void * b)8619 int xodtemplate_skiplist_compare_hostescalation_template(void *a, void *b) {
8620 	xodtemplate_hostescalation *oa = NULL;
8621 	xodtemplate_hostescalation *ob = NULL;
8622 
8623 	oa = (xodtemplate_hostescalation *)a;
8624 	ob = (xodtemplate_hostescalation *)b;
8625 
8626 	if(oa == NULL && ob == NULL)
8627 		return 0;
8628 	if(oa == NULL)
8629 		return 1;
8630 	if(ob == NULL)
8631 		return -1;
8632 
8633 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
8634 	}
8635 
8636 
8637 
xodtemplate_skiplist_compare_hostescalation(void * a,void * b)8638 int xodtemplate_skiplist_compare_hostescalation(void *a, void *b) {
8639 	xodtemplate_hostescalation *oa = NULL;
8640 	xodtemplate_hostescalation *ob = NULL;
8641 
8642 	oa = (xodtemplate_hostescalation *)a;
8643 	ob = (xodtemplate_hostescalation *)b;
8644 
8645 	if(oa == NULL && ob == NULL)
8646 		return 0;
8647 	if(oa == NULL)
8648 		return 1;
8649 	if(ob == NULL)
8650 		return -1;
8651 
8652 	return skiplist_compare_text(oa->host_name, NULL, ob->host_name, NULL);
8653 	}
8654 
8655 
8656 
xodtemplate_skiplist_compare_serviceescalation_template(void * a,void * b)8657 int xodtemplate_skiplist_compare_serviceescalation_template(void *a, void *b) {
8658 	xodtemplate_serviceescalation *oa = NULL;
8659 	xodtemplate_serviceescalation *ob = NULL;
8660 
8661 	oa = (xodtemplate_serviceescalation *)a;
8662 	ob = (xodtemplate_serviceescalation *)b;
8663 
8664 	if(oa == NULL && ob == NULL)
8665 		return 0;
8666 	if(oa == NULL)
8667 		return 1;
8668 	if(ob == NULL)
8669 		return -1;
8670 
8671 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
8672 	}
8673 
8674 
8675 
xodtemplate_skiplist_compare_serviceescalation(void * a,void * b)8676 int xodtemplate_skiplist_compare_serviceescalation(void *a, void *b) {
8677 	xodtemplate_serviceescalation *oa = NULL;
8678 	xodtemplate_serviceescalation *ob = NULL;
8679 
8680 	oa = (xodtemplate_serviceescalation *)a;
8681 	ob = (xodtemplate_serviceescalation *)b;
8682 
8683 	if(oa == NULL && ob == NULL)
8684 		return 0;
8685 	if(oa == NULL)
8686 		return 1;
8687 	if(ob == NULL)
8688 		return -1;
8689 
8690 	return skiplist_compare_text(oa->host_name, oa->service_description, ob->host_name, ob->service_description);
8691 	}
8692 
8693 
8694 
xodtemplate_skiplist_compare_hostextinfo_template(void * a,void * b)8695 int xodtemplate_skiplist_compare_hostextinfo_template(void *a, void *b) {
8696 	xodtemplate_hostextinfo *oa = NULL;
8697 	xodtemplate_hostextinfo *ob = NULL;
8698 
8699 	oa = (xodtemplate_hostextinfo *)a;
8700 	ob = (xodtemplate_hostextinfo *)b;
8701 
8702 	if(oa == NULL && ob == NULL)
8703 		return 0;
8704 	if(oa == NULL)
8705 		return 1;
8706 	if(ob == NULL)
8707 		return -1;
8708 
8709 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
8710 	}
8711 
8712 
8713 
xodtemplate_skiplist_compare_serviceextinfo_template(void * a,void * b)8714 int xodtemplate_skiplist_compare_serviceextinfo_template(void *a, void *b) {
8715 	xodtemplate_serviceextinfo *oa = NULL;
8716 	xodtemplate_serviceextinfo *ob = NULL;
8717 
8718 	oa = (xodtemplate_serviceextinfo *)a;
8719 	ob = (xodtemplate_serviceextinfo *)b;
8720 
8721 	if(oa == NULL && ob == NULL)
8722 		return 0;
8723 	if(oa == NULL)
8724 		return 1;
8725 	if(ob == NULL)
8726 		return -1;
8727 
8728 	return skiplist_compare_text(oa->name, NULL, ob->name, NULL);
8729 	}
8730 
8731 
8732 
8733 
8734 /******************************************************************/
8735 /********************** CLEANUP FUNCTIONS *************************/
8736 /******************************************************************/
8737 
8738 /* frees memory */
xodtemplate_free_memory(void)8739 int xodtemplate_free_memory(void) {
8740 	xodtemplate_timeperiod *this_timeperiod = NULL;
8741 	xodtemplate_timeperiod *next_timeperiod = NULL;
8742 	xodtemplate_daterange *this_daterange = NULL;
8743 	xodtemplate_daterange *next_daterange = NULL;
8744 	xodtemplate_command *this_command = NULL;
8745 	xodtemplate_command *next_command = NULL;
8746 	xodtemplate_contactgroup *this_contactgroup = NULL;
8747 	xodtemplate_contactgroup *next_contactgroup = NULL;
8748 	xodtemplate_hostgroup *this_hostgroup = NULL;
8749 	xodtemplate_hostgroup *next_hostgroup = NULL;
8750 	xodtemplate_servicegroup *this_servicegroup = NULL;
8751 	xodtemplate_servicegroup *next_servicegroup = NULL;
8752 	xodtemplate_contact *this_contact = NULL;
8753 	xodtemplate_contact *next_contact = NULL;
8754 	xodtemplate_host *this_host = NULL;
8755 	xodtemplate_host *next_host = NULL;
8756 	xodtemplate_service *this_service = NULL;
8757 	xodtemplate_service *next_service = NULL;
8758 	xodtemplate_customvariablesmember *this_customvariablesmember = NULL;
8759 	xodtemplate_customvariablesmember *next_customvariablesmember = NULL;
8760 	register int x = 0;
8761 
8762 
8763 	/* free memory allocated to timeperiod list */
8764 	for(this_timeperiod = xodtemplate_timeperiod_list; this_timeperiod != NULL; this_timeperiod = next_timeperiod) {
8765 		next_timeperiod = this_timeperiod->next;
8766 		my_free(this_timeperiod->template);
8767 		my_free(this_timeperiod->name);
8768 		if (!this_timeperiod->register_object) {
8769 			my_free(this_timeperiod->timeperiod_name);
8770 			my_free(this_timeperiod->alias);
8771 		}
8772 		for(x = 0; x < 7; x++)
8773 			my_free(this_timeperiod->timeranges[x]);
8774 		for(x = 0; x < DATERANGE_TYPES; x++) {
8775 			for(this_daterange = this_timeperiod->exceptions[x]; this_daterange != NULL; this_daterange = next_daterange) {
8776 				next_daterange = this_daterange->next;
8777 				my_free(this_daterange->timeranges);
8778 				my_free(this_daterange);
8779 				}
8780 			}
8781 		my_free(this_timeperiod->exclusions);
8782 		my_free(this_timeperiod);
8783 		}
8784 	xodtemplate_timeperiod_list = NULL;
8785 	xodtemplate_timeperiod_list_tail = NULL;
8786 
8787 	/* free memory allocated to command list */
8788 	for(this_command = xodtemplate_command_list; this_command != NULL; this_command = next_command) {
8789 		next_command = this_command->next;
8790 		my_free(this_command->template);
8791 		my_free(this_command->name);
8792 		if (!this_command->register_object) {
8793 			my_free(this_command->command_name);
8794 			my_free(this_command->command_line);
8795 		}
8796 		my_free(this_command);
8797 		}
8798 	xodtemplate_command_list = NULL;
8799 	xodtemplate_command_list_tail = NULL;
8800 
8801 	/* free memory allocated to contactgroup list */
8802 	for(this_contactgroup = xodtemplate_contactgroup_list; this_contactgroup != NULL; this_contactgroup = next_contactgroup) {
8803 		next_contactgroup = this_contactgroup->next;
8804 		my_free(this_contactgroup->template);
8805 		my_free(this_contactgroup->name);
8806 		my_free(this_contactgroup->members);
8807 		my_free(this_contactgroup->contactgroup_members);
8808 		bitmap_destroy(this_contactgroup->member_map);
8809 		free_objectlist(&this_contactgroup->member_list);
8810 		free_objectlist(&this_contactgroup->group_list);
8811 		if (!this_contactgroup->register_object) {
8812 			my_free(this_contactgroup->contactgroup_name);
8813 			my_free(this_contactgroup->alias);
8814 		}
8815 		my_free(this_contactgroup);
8816 		}
8817 	xodtemplate_contactgroup_list = NULL;
8818 	xodtemplate_contactgroup_list_tail = NULL;
8819 
8820 	/* free memory allocated to hostgroup list */
8821 	for(this_hostgroup = xodtemplate_hostgroup_list; this_hostgroup != NULL; this_hostgroup = next_hostgroup) {
8822 		next_hostgroup = this_hostgroup->next;
8823 		my_free(this_hostgroup->template);
8824 		my_free(this_hostgroup->name);
8825 		my_free(this_hostgroup->members);
8826 		my_free(this_hostgroup->hostgroup_members);
8827 		bitmap_destroy(this_hostgroup->member_map);
8828 		free_objectlist(&this_hostgroup->member_list);
8829 		free_objectlist(&this_hostgroup->group_list);
8830 		if (!this_hostgroup->register_object) {
8831 			my_free(this_hostgroup->hostgroup_name);
8832 			my_free(this_hostgroup->alias);
8833 			my_free(this_hostgroup->notes);
8834 			my_free(this_hostgroup->notes_url);
8835 			my_free(this_hostgroup->action_url);
8836 		}
8837 		my_free(this_hostgroup);
8838 		}
8839 	xodtemplate_hostgroup_list = NULL;
8840 	xodtemplate_hostgroup_list_tail = NULL;
8841 
8842 	/* free memory allocated to servicegroup list */
8843 	for(this_servicegroup = xodtemplate_servicegroup_list; this_servicegroup != NULL; this_servicegroup = next_servicegroup) {
8844 		next_servicegroup = this_servicegroup->next;
8845 		my_free(this_servicegroup->members);
8846 		my_free(this_servicegroup->servicegroup_members);
8847 		bitmap_destroy(this_servicegroup->member_map);
8848 		free_objectlist(&this_servicegroup->member_list);
8849 		free_objectlist(&this_servicegroup->group_list);
8850 		my_free(this_servicegroup->template);
8851 		my_free(this_servicegroup->name);
8852 		if (!this_servicegroup->register_object) {
8853 			my_free(this_servicegroup->servicegroup_name);
8854 			my_free(this_servicegroup->alias);
8855 			my_free(this_servicegroup->notes);
8856 			my_free(this_servicegroup->notes_url);
8857 			my_free(this_servicegroup->action_url);
8858 		}
8859 		my_free(this_servicegroup);
8860 		}
8861 	xodtemplate_servicegroup_list = NULL;
8862 	xodtemplate_servicegroup_list_tail = NULL;
8863 
8864 	/* free memory allocated to contact list */
8865 	for(this_contact = xodtemplate_contact_list; this_contact != NULL; this_contact = next_contact) {
8866 		next_contact = this_contact->next;
8867 		/* free custom variables */
8868 		this_customvariablesmember = this_contact->custom_variables;
8869 		while(this_customvariablesmember != NULL) {
8870 			next_customvariablesmember = this_customvariablesmember->next;
8871 			my_free(this_customvariablesmember->variable_name);
8872 			my_free(this_customvariablesmember->variable_value);
8873 			my_free(this_customvariablesmember);
8874 			this_customvariablesmember = next_customvariablesmember;
8875 			}
8876 		my_free(this_contact->template);
8877 		my_free(this_contact->name);
8878 		my_free(this_contact->contact_groups);
8879 		my_free(this_contact->service_notification_period);
8880 		my_free(this_contact->service_notification_commands);
8881 		my_free(this_contact->host_notification_period);
8882 		my_free(this_contact->host_notification_commands);
8883 		if (!this_contact->register_object) {
8884 			my_free(this_contact->contact_name);
8885 			my_free(this_contact->alias);
8886 			my_free(this_contact->email);
8887 			my_free(this_contact->pager);
8888 			for (x = 0; x < MAX_XODTEMPLATE_CONTACT_ADDRESSES; x++)
8889 				my_free(this_contact->address[x]);
8890 			}
8891 		my_free(this_contact);
8892 		}
8893 	xodtemplate_contact_list = NULL;
8894 	xodtemplate_contact_list_tail = NULL;
8895 
8896 	/* free memory allocated to host list */
8897 	for(this_host = xodtemplate_host_list; this_host != NULL; this_host = next_host) {
8898 		next_host = this_host->next;
8899 		/* free custom variables */
8900 		this_customvariablesmember = this_host->custom_variables;
8901 		while(this_customvariablesmember != NULL) {
8902 			next_customvariablesmember = this_customvariablesmember->next;
8903 			my_free(this_customvariablesmember->variable_name);
8904 			my_free(this_customvariablesmember->variable_value);
8905 			my_free(this_customvariablesmember);
8906 			this_customvariablesmember = next_customvariablesmember;
8907 			}
8908 
8909 		my_free(this_host->template);
8910 		my_free(this_host->name);
8911 		my_free(this_host->parents);
8912 		my_free(this_host->host_groups);
8913 		my_free(this_host->check_period);
8914 		my_free(this_host->contact_groups);
8915 		my_free(this_host->contacts);
8916 		my_free(this_host->notification_period);
8917 		if (!this_host->register_object) {
8918 			my_free(this_host->host_name);
8919 			my_free(this_host->alias);
8920 			my_free(this_host->display_name);
8921 			my_free(this_host->address);
8922 			my_free(this_host->check_command);
8923 			my_free(this_host->event_handler);
8924 			my_free(this_host->notes);
8925 			my_free(this_host->notes_url);
8926 			my_free(this_host->action_url);
8927 			my_free(this_host->icon_image);
8928 			my_free(this_host->icon_image_alt);
8929 			my_free(this_host->statusmap_image);
8930 			my_free(this_host->vrml_image);
8931 			}
8932 		my_free(this_host);
8933 		}
8934 	xodtemplate_host_list = NULL;
8935 	xodtemplate_host_list_tail = NULL;
8936 
8937 	/* free memory allocated to service list */
8938 	for(this_service = xodtemplate_service_list; this_service != NULL; this_service = next_service) {
8939 		next_service = this_service->next;
8940 		my_free(this_service->contact_groups);
8941 		my_free(this_service->contacts);
8942 		my_free(this_service->service_groups);
8943 
8944 		if(this_service->is_copy == FALSE || !this_service->register_object) {
8945 			/* free custom variables */
8946 			this_customvariablesmember = this_service->custom_variables;
8947 			while(this_customvariablesmember != NULL) {
8948 				next_customvariablesmember = this_customvariablesmember->next;
8949 				my_free(this_customvariablesmember->variable_name);
8950 				my_free(this_customvariablesmember->variable_value);
8951 				my_free(this_customvariablesmember);
8952 				this_customvariablesmember = next_customvariablesmember;
8953 				}
8954 
8955 			my_free(this_service->template);
8956 			my_free(this_service->name);
8957 			my_free(this_service->parents);
8958 			my_free(this_service->display_name);
8959 			my_free(this_service->check_command);
8960 			my_free(this_service->check_period);
8961 			my_free(this_service->event_handler);
8962 			my_free(this_service->notification_period);
8963 			my_free(this_service->notes);
8964 			my_free(this_service->notes_url);
8965 			my_free(this_service->action_url);
8966 			my_free(this_service->icon_image);
8967 			my_free(this_service->icon_image_alt);
8968 			my_free(this_service->hostgroup_name);
8969 			my_free(this_service->service_description);
8970 			}
8971 		my_free(this_service);
8972 		}
8973 	xodtemplate_service_list = NULL;
8974 	xodtemplate_service_list_tail = NULL;
8975 
8976 	/*
8977 	 * extinfo objects are free()'d while they're parsed, as are
8978 	 * dependencies and escalations
8979 	 */
8980 	xodtemplate_hostextinfo_list = NULL;
8981 	xodtemplate_hostextinfo_list_tail = NULL;
8982 	xodtemplate_serviceextinfo_list = NULL;
8983 	xodtemplate_serviceextinfo_list_tail = NULL;
8984 
8985 	/* free memory for the config file names */
8986 	for(x = 0; x < xodtemplate_current_config_file; x++)
8987 		my_free(xodtemplate_config_files[x]);
8988 	my_free(xodtemplate_config_files);
8989 	xodtemplate_current_config_file = 0;
8990 
8991 	/* free skiplists */
8992 	xodtemplate_free_xobject_skiplists();
8993 
8994 	return OK;
8995 	}
8996 
8997 
8998 
8999 
9000 /* adds a member to a list */
xodtemplate_add_member_to_memberlist(xodtemplate_memberlist ** list,char * name1,char * name2)9001 int xodtemplate_add_member_to_memberlist(xodtemplate_memberlist **list, char *name1, char *name2) {
9002 	xodtemplate_memberlist *temp_item = NULL;
9003 	xodtemplate_memberlist *new_item = NULL;
9004 	int error = FALSE;
9005 
9006 	if(list == NULL)
9007 		return ERROR;
9008 	if(name1 == NULL)
9009 		return ERROR;
9010 
9011 	/* skip this member if its already in the list */
9012 	for(temp_item = *list; temp_item; temp_item = temp_item->next) {
9013 		if(!strcmp(temp_item->name1, name1)) {
9014 			if(temp_item->name2 == NULL) {
9015 				if(name2 == NULL)
9016 					break;
9017 				}
9018 			else if(name2 != NULL && !strcmp(temp_item->name2, name2))
9019 				break;
9020 			}
9021 		}
9022 	if(temp_item)
9023 		return OK;
9024 
9025 	/* allocate zero'd out memory for a new list item */
9026 	if((new_item = (xodtemplate_memberlist *)calloc(1, sizeof(xodtemplate_memberlist))) == NULL)
9027 		return ERROR;
9028 
9029 	/* save the member name(s) */
9030 	if(name1) {
9031 		if((new_item->name1 = (char *)strdup(name1)) == NULL)
9032 			error = TRUE;
9033 		}
9034 	if(name2) {
9035 		if((new_item->name2 = (char *)strdup(name2)) == NULL)
9036 			error = TRUE;
9037 		}
9038 
9039 	if(error == TRUE) {
9040 		my_free(new_item->name1);
9041 		my_free(new_item->name2);
9042 		my_free(new_item);
9043 		return ERROR;
9044 		}
9045 
9046 	/* add new item to head of list */
9047 	new_item->next = *list;
9048 	*list = new_item;
9049 
9050 	return OK;
9051 	}
9052 
9053 
9054 /* frees memory allocated to a temporary member list */
xodtemplate_free_memberlist(xodtemplate_memberlist ** temp_list)9055 int xodtemplate_free_memberlist(xodtemplate_memberlist **temp_list) {
9056 	xodtemplate_memberlist *this_memberlist = NULL;
9057 	xodtemplate_memberlist *next_memberlist = NULL;
9058 
9059 	/* free memory allocated to member name list */
9060 	for(this_memberlist = *temp_list; this_memberlist != NULL; this_memberlist = next_memberlist) {
9061 		next_memberlist = this_memberlist->next;
9062 		my_free(this_memberlist->name1);
9063 		my_free(this_memberlist->name2);
9064 		my_free(this_memberlist);
9065 		}
9066 
9067 	*temp_list = NULL;
9068 
9069 	return OK;
9070 	}
9071 
9072 
9073 /* remove an entry from the member list */
xodtemplate_remove_memberlist_item(xodtemplate_memberlist * item,xodtemplate_memberlist ** list)9074 void xodtemplate_remove_memberlist_item(xodtemplate_memberlist *item, xodtemplate_memberlist **list) {
9075 	xodtemplate_memberlist *temp_item = NULL;
9076 
9077 	if(item == NULL || list == NULL)
9078 		return;
9079 
9080 	if(*list == NULL)
9081 		return;
9082 
9083 	if(*list == item)
9084 		*list = item->next;
9085 
9086 	else {
9087 
9088 		for(temp_item = *list; temp_item != NULL; temp_item = temp_item->next) {
9089 			if(temp_item->next == item) {
9090 				temp_item->next = item->next;
9091 				break;
9092 				}
9093 			}
9094 		}
9095 
9096 	my_free(item->name1);
9097 	my_free(item->name2);
9098 	my_free(item);
9099 
9100 	return;
9101 	}
9102 
9103 
9104 /******************************************************************/
9105 /********************** UTILITY FUNCTIONS *************************/
9106 /******************************************************************/
9107 
9108 
9109 /* expands contacts */
xodtemplate_expand_contacts(objectlist ** ret,bitmap * reject_map,char * contacts,int _config_file,int _start_line)9110 int xodtemplate_expand_contacts(objectlist **ret, bitmap *reject_map, char *contacts, int _config_file, int _start_line) {
9111 	char *contact_names = NULL;
9112 	char *temp_ptr = NULL;
9113 	xodtemplate_contact *temp_contact = NULL;
9114 	regex_t preg;
9115 	int found_match = TRUE;
9116 	int reject_item = FALSE;
9117 	int use_regexp = FALSE;
9118 
9119 	if(ret == NULL || contacts == NULL)
9120 		return ERROR;
9121 
9122 	*ret = NULL;
9123 
9124 	if((contact_names = (char *)strdup(contacts)) == NULL)
9125 		return ERROR;
9126 
9127 	/* expand each contact name */
9128 	for(temp_ptr = strtok(contact_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) {
9129 
9130 		found_match = FALSE;
9131 		reject_item = FALSE;
9132 
9133 		/* strip trailing spaces */
9134 		strip(temp_ptr);
9135 
9136 		/* should we use regular expression matching? */
9137 		if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\.")))
9138 			use_regexp = TRUE;
9139 
9140 		/* use regular expression matching */
9141 		if(use_regexp == TRUE) {
9142 
9143 			/* compile regular expression */
9144 			if(regcomp(&preg, temp_ptr, REG_EXTENDED)) {
9145 				my_free(contact_names);
9146 				return ERROR;
9147 				}
9148 
9149 			/* test match against all contacts */
9150 			for(temp_contact = xodtemplate_contact_list; temp_contact != NULL; temp_contact = temp_contact->next) {
9151 
9152 				if(temp_contact->contact_name == NULL)
9153 					continue;
9154 
9155 				/* skip this contact if it did not match the expression */
9156 				if(regexec(&preg, temp_contact->contact_name, 0, NULL, 0))
9157 					continue;
9158 
9159 				found_match = TRUE;
9160 
9161 				/* don't add contacts that shouldn't be registered */
9162 				if(temp_contact->register_object == FALSE)
9163 					continue;
9164 
9165 				/* add contact to list */
9166 				add_object_to_objectlist(ret, temp_contact);
9167 				}
9168 
9169 			/* free memory allocated to compiled regexp */
9170 			regfree(&preg);
9171 			}
9172 
9173 		/* use standard matching... */
9174 		else {
9175 
9176 			/* return a list of all contacts */
9177 			if(!strcmp(temp_ptr, "*")) {
9178 
9179 				found_match = TRUE;
9180 
9181 				for(temp_contact = xodtemplate_contact_list; temp_contact != NULL; temp_contact = temp_contact->next) {
9182 
9183 					if(temp_contact->contact_name == NULL)
9184 						continue;
9185 
9186 					/* don't add contacts that shouldn't be registered */
9187 					if(temp_contact->register_object == FALSE)
9188 						continue;
9189 
9190 					/* add contact to list */
9191 					add_object_to_objectlist(ret, temp_contact);
9192 					}
9193 				}
9194 
9195 			/* else this is just a single contact... */
9196 			else {
9197 
9198 				/* this contact should be excluded (rejected) */
9199 				if(temp_ptr[0] == '!') {
9200 					reject_item = TRUE;
9201 					temp_ptr++;
9202 					}
9203 
9204 				/* find the contact */
9205 				temp_contact = xodtemplate_find_real_contact(temp_ptr);
9206 				if(temp_contact != NULL) {
9207 
9208 					found_match = TRUE;
9209 
9210 					/* add contact to list */
9211 					if(reject_item) {
9212 						bitmap_set(reject_map, temp_contact->id);
9213 						}
9214 					else {
9215 						add_object_to_objectlist(ret, temp_contact);
9216 						}
9217 					}
9218 				}
9219 			}
9220 
9221 		if(found_match == FALSE) {
9222 			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);
9223 			break;
9224 			}
9225 		}
9226 
9227 	/* free memory */
9228 	my_free(contact_names);
9229 
9230 	if(found_match == FALSE)
9231 		return ERROR;
9232 
9233 	return OK;
9234 	}
9235 
9236 
9237 #ifdef NSCORE
9238 
9239 /*
9240  * expands a comma-delimited list of hostgroups and/or hosts to
9241  * an objectlist of hosts. This cannot be called until hostgroups
9242  * have been recombobulated.
9243  */
xodtemplate_expand_hostgroups_and_hosts(char * hostgroups,char * hosts,int _config_file,int _start_line)9244 objectlist *xodtemplate_expand_hostgroups_and_hosts(char *hostgroups, char *hosts, int _config_file, int _start_line) {
9245 	objectlist *ret = NULL, *glist = NULL, *hlist, *list = NULL, *next;
9246 	bitmap *reject;
9247 	int result;
9248 
9249 	reject = bitmap_create(xodcount.hosts);
9250 	if(!reject) {
9251 		logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Unable to create reject map for expanding hosts and hostgroups\n");
9252 		return NULL;
9253 		}
9254 
9255 	/*
9256 	 * process host names first. If they're explicitly added we must obey
9257 	 */
9258 	if(hosts != NULL) {
9259 		/* expand hosts */
9260 		result = xodtemplate_expand_hosts(&ret, reject, hosts, _config_file, _start_line);
9261 		if(result != OK) {
9262 			free_objectlist(&glist);
9263 			free_objectlist(&ret);
9264 			bitmap_destroy(reject);
9265 			return NULL;
9266 			}
9267 		}
9268 
9269 	/* process list of hostgroups... */
9270 	if(hostgroups != NULL) {
9271 		/* expand host */
9272 		result = xodtemplate_expand_hostgroups(&glist, reject, hostgroups, _config_file, _start_line);
9273 		if(result != OK) {
9274 			logit(NSLOG_CONFIG_ERROR, TRUE, "Failed to expand hostgroups '%s' to something sensible\n", hostgroups);
9275 			free_objectlist(&glist);
9276 			bitmap_destroy(reject);
9277 			return NULL;
9278 			}
9279 		}
9280 
9281 	/*
9282 	 * add hostgroup hosts to ret, taking care not to add any that are
9283 	 * in the rejected list
9284 	 */
9285 	for(list = glist; list; list = next) {
9286 		xodtemplate_hostgroup *hg = (xodtemplate_hostgroup *)list->object_ptr;
9287 		next = list->next;
9288 		free(list); /* free it as we go along */
9289 		for(hlist = hg->member_list; hlist; hlist = hlist->next) {
9290 			xodtemplate_host *h = (xodtemplate_host *)hlist->object_ptr;
9291 			if(bitmap_isset(reject, h->id))
9292 				continue;
9293 			add_object_to_objectlist(&ret, h);
9294 		}
9295 	}
9296 	bitmap_destroy(reject);
9297 
9298 	return ret;
9299 	}
9300 
9301 #endif
9302 
9303 /*
9304  * expands hostgroups.
9305  * list will be populated with all selected hostgroups on success
9306  * and set to NULL on errors.
9307  * reject_map marks rejected *hosts* from rejected hostgroups
9308  * This can only be called after hostgroups are recombobulated.
9309  * returns ERROR on error and OK on success.
9310  */
xodtemplate_expand_hostgroups(objectlist ** list,bitmap * reject_map,char * hostgroups,int _config_file,int _start_line)9311 int xodtemplate_expand_hostgroups(objectlist **list, bitmap *reject_map, char *hostgroups, int _config_file, int _start_line) {
9312 	char *hostgroup_names = NULL;
9313 	char *temp_ptr = NULL;
9314 	xodtemplate_hostgroup *temp_hostgroup = NULL;
9315 	regex_t preg;
9316 	int found_match = TRUE;
9317 	int reject_item = FALSE;
9318 	int use_regexp = FALSE;
9319 
9320 	if(list == NULL || hostgroups == NULL)
9321 		return ERROR;
9322 
9323 	*list = NULL;
9324 
9325 	/* allocate memory for hostgroup name list */
9326 	if((hostgroup_names = (char *)strdup(hostgroups)) == NULL)
9327 		return ERROR;
9328 
9329 	for(temp_ptr = strtok(hostgroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) {
9330 
9331 		found_match = FALSE;
9332 		reject_item = FALSE;
9333 
9334 		/* strip trailing spaces */
9335 		strip(temp_ptr);
9336 
9337 		/* should we use regular expression matching? */
9338 		if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\.")))
9339 			use_regexp = TRUE;
9340 		else
9341 			use_regexp = FALSE;
9342 
9343 		/* use regular expression matching */
9344 		if(use_regexp == TRUE) {
9345 
9346 			/* compile regular expression */
9347 			if(regcomp(&preg, temp_ptr, REG_EXTENDED)) {
9348 				my_free(hostgroup_names);
9349 				return ERROR;
9350 				}
9351 
9352 			/* test match against all hostgroup names */
9353 			for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) {
9354 
9355 				if(temp_hostgroup->hostgroup_name == NULL)
9356 					continue;
9357 
9358 				/* skip this hostgroup if it did not match the expression */
9359 				if(regexec(&preg, temp_hostgroup->hostgroup_name, 0, NULL, 0))
9360 					continue;
9361 
9362 				found_match = TRUE;
9363 
9364 				/* don't add hostgroups that shouldn't be registered */
9365 				if(temp_hostgroup->register_object == FALSE)
9366 					continue;
9367 
9368 				add_object_to_objectlist(list, temp_hostgroup);
9369 				}
9370 
9371 			/* free memory allocated to compiled regexp */
9372 			regfree(&preg);
9373 			}
9374 
9375 		/* use standard matching... */
9376 		else {
9377 
9378 			/* return a list of all hostgroups */
9379 			if(!strcmp(temp_ptr, "*")) {
9380 
9381 				found_match = TRUE;
9382 
9383 				for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) {
9384 
9385 					/* don't add hostgroups that shouldn't be registered */
9386 					if(temp_hostgroup->register_object == FALSE)
9387 						continue;
9388 
9389 					/* add hostgroup to list */
9390 					add_object_to_objectlist(list, temp_hostgroup);
9391 					}
9392 				}
9393 
9394 			/* else this is just a single hostgroup... */
9395 			else {
9396 
9397 				/* this hostgroup should be excluded (rejected) */
9398 				if(temp_ptr[0] == '!') {
9399 					reject_item = TRUE;
9400 					temp_ptr++;
9401 					}
9402 
9403 				/* find the hostgroup */
9404 				temp_hostgroup = xodtemplate_find_real_hostgroup(temp_ptr);
9405 				if(temp_hostgroup != NULL) {
9406 					found_match = TRUE;
9407 
9408 					if(reject_item) {
9409 						bitmap_unite(reject_map, temp_hostgroup->member_map);
9410 						}
9411 					else {
9412 						/* add hostgroup members to proper list */
9413 						add_object_to_objectlist(list, temp_hostgroup);
9414 						}
9415 					}
9416 				}
9417 			}
9418 
9419 		if(found_match == FALSE) {
9420 			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);
9421 			break;
9422 			}
9423 		}
9424 
9425 	/* free memory */
9426 	my_free(hostgroup_names);
9427 
9428 	if(found_match == FALSE)
9429 		return ERROR;
9430 
9431 	return OK;
9432 	}
9433 
9434 
9435 
9436 /* expands hosts */
xodtemplate_expand_hosts(objectlist ** list,bitmap * reject_map,char * hosts,int _config_file,int _start_line)9437 int xodtemplate_expand_hosts(objectlist **list, bitmap *reject_map, char *hosts, int _config_file, int _start_line) {
9438 	char *temp_ptr = NULL;
9439 	xodtemplate_host *temp_host = NULL;
9440 	regex_t preg;
9441 	int found_match = TRUE;
9442 	int reject_item = FALSE;
9443 	int use_regexp = FALSE;
9444 
9445 	if(list == NULL || hosts == NULL)
9446 		return ERROR;
9447 
9448 	/* expand each host name */
9449 	for(temp_ptr = strtok(hosts, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) {
9450 
9451 		found_match = FALSE;
9452 		reject_item = FALSE;
9453 
9454 		/* strip trailing spaces */
9455 		strip(temp_ptr);
9456 
9457 		/* should we use regular expression matching? */
9458 		if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\.")))
9459 			use_regexp = TRUE;
9460 
9461 		/* use regular expression matching */
9462 		if(use_regexp == TRUE) {
9463 
9464 			/* compile regular expression */
9465 			if(regcomp(&preg, temp_ptr, REG_EXTENDED)) {
9466 				return ERROR;
9467 				}
9468 
9469 			/* test match against all hosts */
9470 			for(temp_host = xodtemplate_host_list; temp_host != NULL; temp_host = temp_host->next) {
9471 
9472 				if(temp_host->host_name == NULL)
9473 					continue;
9474 
9475 				/* skip this host if it did not match the expression */
9476 				if(regexec(&preg, temp_host->host_name, 0, NULL, 0))
9477 					continue;
9478 
9479 				found_match = TRUE;
9480 
9481 				/* don't add hosts that shouldn't be registered */
9482 				if(temp_host->register_object == FALSE)
9483 					continue;
9484 
9485 				/* add host to list */
9486 				add_object_to_objectlist(list, temp_host);
9487 				}
9488 
9489 			/* free memory allocated to compiled regexp */
9490 			regfree(&preg);
9491 			}
9492 
9493 		/* use standard matching... */
9494 		else {
9495 
9496 			/* return a list of all hosts */
9497 			if(!strcmp(temp_ptr, "*")) {
9498 
9499 				found_match = TRUE;
9500 
9501 				for(temp_host = xodtemplate_host_list; temp_host != NULL; temp_host = temp_host->next) {
9502 
9503 					if(temp_host->host_name == NULL)
9504 						continue;
9505 
9506 					/* don't add hosts that shouldn't be registered */
9507 					if(temp_host->register_object == FALSE)
9508 						continue;
9509 
9510 					/* add host to list */
9511 					add_object_to_objectlist(list, temp_host);
9512 					}
9513 				}
9514 
9515 			/* else this is just a single host... */
9516 			else {
9517 
9518 				/* this host should be excluded (rejected) */
9519 				if(temp_ptr[0] == '!') {
9520 					reject_item = TRUE;
9521 					temp_ptr++;
9522 					}
9523 
9524 				/* find the host */
9525 				temp_host = xodtemplate_find_real_host(temp_ptr);
9526 				if(temp_host != NULL) {
9527 
9528 					found_match = TRUE;
9529 
9530 					/* add host to list */
9531 					if(!reject_item) {
9532 						add_object_to_objectlist(list, temp_host);
9533 						}
9534 					else {
9535 						bitmap_set(reject_map, temp_host->id);
9536 						}
9537 					}
9538 				}
9539 			}
9540 
9541 		if(found_match == FALSE) {
9542 			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);
9543 			break;
9544 			}
9545 		}
9546 
9547 	if(found_match == FALSE)
9548 		return ERROR;
9549 
9550 	return OK;
9551 	}
9552 
9553 
9554 /*
9555  * expands servicegroups.
9556  * list will hold all selected servicegroups.
9557  * reject will map services from all rejected servicegroups
9558  * This can only be called after servicegroups are recombobulated.
9559  */
xodtemplate_expand_servicegroups(objectlist ** list,bitmap * reject,char * servicegroups,int _config_file,int _start_line)9560 int xodtemplate_expand_servicegroups(objectlist **list, bitmap *reject, char *servicegroups, int _config_file, int _start_line) {
9561 	xodtemplate_servicegroup  *temp_servicegroup = NULL;
9562 	regex_t preg;
9563 	char *servicegroup_names = NULL;
9564 	char *temp_ptr = NULL;
9565 	int found_match = TRUE;
9566 	int reject_item = FALSE;
9567 	int use_regexp = FALSE;
9568 
9569 	if(list == NULL)
9570 		return ERROR;
9571 	if(servicegroups == NULL)
9572 		return OK;
9573 
9574 	/* allocate memory for servicegroup name list */
9575 	if((servicegroup_names = (char *)strdup(servicegroups)) == NULL)
9576 		return ERROR;
9577 
9578 	/* expand each servicegroup */
9579 	for(temp_ptr = strtok(servicegroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) {
9580 
9581 		found_match = FALSE;
9582 		reject_item = FALSE;
9583 
9584 		/* strip trailing spaces */
9585 		strip(temp_ptr);
9586 
9587 		/* should we use regular expression matching? */
9588 		if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\.")))
9589 			use_regexp = TRUE;
9590 		else
9591 			use_regexp = FALSE;
9592 
9593 		/* use regular expression matching */
9594 		if(use_regexp == TRUE) {
9595 
9596 			/* compile regular expression */
9597 			if(regcomp(&preg, temp_ptr, REG_EXTENDED)) {
9598 				my_free(servicegroup_names);
9599 				return ERROR;
9600 				}
9601 
9602 			/* test match against all servicegroup names */
9603 			for(temp_servicegroup = xodtemplate_servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) {
9604 
9605 				if(temp_servicegroup->servicegroup_name == NULL)
9606 					continue;
9607 
9608 				/* skip this servicegroup if it did not match the expression */
9609 				if(regexec(&preg, temp_servicegroup->servicegroup_name, 0, NULL, 0))
9610 					continue;
9611 
9612 				found_match = TRUE;
9613 
9614 				/* don't add servicegroups that shouldn't be registered */
9615 				if(temp_servicegroup->register_object == FALSE)
9616 					continue;
9617 
9618 				/* add servicegroup to list */
9619 				add_object_to_objectlist(list, temp_servicegroup);
9620 				}
9621 
9622 			/* free memory allocated to compiled regexp */
9623 			regfree(&preg);
9624 			}
9625 
9626 		/* use standard matching... */
9627 		else {
9628 
9629 			/* return a list of all servicegroups */
9630 			if(!strcmp(temp_ptr, "*")) {
9631 
9632 				found_match = TRUE;
9633 
9634 				for(temp_servicegroup = xodtemplate_servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) {
9635 
9636 					/* don't add servicegroups that shouldn't be registered */
9637 					if(temp_servicegroup->register_object == FALSE)
9638 						continue;
9639 
9640 					/* add servicegroup to list */
9641 					prepend_object_to_objectlist(list, temp_servicegroup);
9642 					}
9643 				}
9644 
9645 			/* else this is just a single servicegroup... */
9646 			else {
9647 
9648 				/* this servicegroup should be excluded (rejected) */
9649 				if(temp_ptr[0] == '!') {
9650 					reject_item = TRUE;
9651 					temp_ptr++;
9652 					}
9653 
9654 				/* find the servicegroup */
9655 				if((temp_servicegroup = xodtemplate_find_real_servicegroup(temp_ptr)) != NULL) {
9656 
9657 					found_match = TRUE;
9658 
9659 					/* add servicegroup members to list */
9660 					if(reject_item)
9661 						bitmap_unite(reject, temp_servicegroup->member_map);
9662 					else
9663 						add_object_to_objectlist(list, temp_servicegroup);
9664 					}
9665 				}
9666 			}
9667 
9668 		/* we didn't find a matching servicegroup */
9669 		if(found_match == FALSE) {
9670 			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);
9671 			break;
9672 			}
9673 		}
9674 
9675 	/* free memory */
9676 	my_free(servicegroup_names);
9677 
9678 	if(found_match == FALSE)
9679 		return ERROR;
9680 
9681 	return OK;
9682 	}
9683 
9684 /* expands services (host name is not expanded) */
xodtemplate_expand_services(objectlist ** list,bitmap * reject_map,char * host_name,char * services,int _config_file,int _start_line)9685 int xodtemplate_expand_services(objectlist **list, bitmap *reject_map, char *host_name, char *services, int _config_file, int _start_line) {
9686 	char *service_names = NULL;
9687 	char *temp_ptr = NULL;
9688 	xodtemplate_service *temp_service = NULL;
9689 #ifndef NSCGI
9690 	regex_t preg;
9691 	regex_t preg2;
9692 	int use_regexp_host = FALSE;
9693 	int use_regexp_service = FALSE;
9694 #endif
9695 	int found_match = TRUE;
9696 	int reject_item = FALSE;
9697 
9698 	if(list == NULL)
9699 		return ERROR;
9700 
9701 	/*
9702 	 * One-step recursion for convenience.
9703 	 * Useful for servicegroups' "members" directive
9704 	 */
9705 	if(host_name == NULL && services != NULL) {
9706 		char *scopy, *next_p, *p1, *p2;
9707 
9708 		if (!(scopy = strdup(services)))
9709 			return ERROR;
9710 		for(next_p = p1 = scopy; next_p; p1 = next_p + 1) {
9711 			p2 = strchr(p1, ',');
9712 			if (!p2) {
9713 				logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Service description missing from list '%s' (config file '%s', starting at line %d)\n",
9714 					  services, xodtemplate_config_file_name(_config_file), _start_line);
9715 				free(scopy);
9716 				return ERROR;
9717 			}
9718 			*p2 = 0;
9719 			while(!*p2 || *p2 == ' ' || *p2 == '\t')
9720 				p2++;
9721 			while(*p1 == ',' || *p1 == ' ' || *p1 == '\t')
9722 				p1++;
9723 			next_p = strchr(p2 + 1, ',');
9724 			if(next_p)
9725 				*next_p = 0;
9726 			strip(p1);
9727 			strip(p2);
9728 
9729 			/* now we have arguments we can handle safely, so do that */
9730 			if(xodtemplate_expand_services(list, reject_map, p1, p2, _config_file, _start_line) != OK) {
9731 				free(scopy);
9732 				return ERROR;
9733 				}
9734 			}
9735 		free(scopy);
9736 		}
9737 	if(host_name == NULL || services == NULL)
9738 		return OK;
9739 
9740 #ifndef NSCGI
9741 	/* should we use regular expression matching for the host name? */
9742 	if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(host_name, "*") || strstr(host_name, "?") || strstr(host_name, "+") || strstr(host_name, "\\.")))
9743 		use_regexp_host = TRUE;
9744 
9745 	/* compile regular expression for host name */
9746 	if(use_regexp_host == TRUE) {
9747 		if(regcomp(&preg2, host_name, REG_EXTENDED))
9748 			return ERROR;
9749 		}
9750 #endif
9751 
9752 	if((service_names = (char *)strdup(services)) == NULL) {
9753 #ifndef NSCGI
9754 		if(use_regexp_host == TRUE)
9755 			regfree(&preg2);
9756 #endif
9757 		return ERROR;
9758 		}
9759 
9760 	/* expand each service description */
9761 	for(temp_ptr = strtok(service_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) {
9762 
9763 		found_match = FALSE;
9764 		reject_item = FALSE;
9765 
9766 		/* strip trailing spaces */
9767 		strip(temp_ptr);
9768 
9769 #ifndef NSCGI
9770 		/* should we use regular expression matching for the service description? */
9771 		if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\.")))
9772 			use_regexp_service = TRUE;
9773 		else
9774 			use_regexp_service = FALSE;
9775 
9776 		/* compile regular expression for service description */
9777 		if(use_regexp_service == TRUE) {
9778 			if(regcomp(&preg, temp_ptr, REG_EXTENDED)) {
9779 				if(use_regexp_host == TRUE)
9780 					regfree(&preg2);
9781 				my_free(service_names);
9782 				return ERROR;
9783 				}
9784 			}
9785 
9786 		/* use regular expression matching */
9787 		if(use_regexp_host == TRUE || use_regexp_service == TRUE) {
9788 
9789 			/* test match against all services */
9790 			for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) {
9791 
9792 				if(temp_service->host_name == NULL || temp_service->service_description == NULL)
9793 					continue;
9794 
9795 				/* skip this service if it doesn't match the host name expression */
9796 				if(use_regexp_host == TRUE) {
9797 					if(regexec(&preg2, temp_service->host_name, 0, NULL, 0))
9798 						continue;
9799 					}
9800 				else {
9801 					if(strcmp(temp_service->host_name, host_name))
9802 						continue;
9803 					}
9804 
9805 				/* skip this service if it doesn't match the service description expression */
9806 				if(use_regexp_service == TRUE) {
9807 					if(regexec(&preg, temp_service->service_description, 0, NULL, 0))
9808 						continue;
9809 					}
9810 				else {
9811 					if(strcmp(temp_service->service_description, temp_ptr))
9812 						continue;
9813 					}
9814 
9815 				found_match = TRUE;
9816 
9817 				/* don't add services that shouldn't be registered */
9818 				if(temp_service->register_object == FALSE)
9819 					continue;
9820 
9821 				/* add service to the list */
9822 				add_object_to_objectlist(list, temp_service);
9823 				}
9824 
9825 			/* free memory allocated to compiled regexp */
9826 			if(use_regexp_service == TRUE)
9827 				regfree(&preg);
9828 			}
9829 
9830 		/* use standard matching... */
9831 		else if(!strcmp(temp_ptr, "*")) {
9832 			/* return a list of all services on the host */
9833 
9834 			found_match = TRUE;
9835 
9836 			for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) {
9837 
9838 				if(temp_service->host_name == NULL || temp_service->service_description == NULL)
9839 					continue;
9840 
9841 				if(strcmp(temp_service->host_name, host_name))
9842 					continue;
9843 
9844 				/* don't add services that shouldn't be registered */
9845 				if(temp_service->register_object == FALSE)
9846 					continue;
9847 
9848 				/* add service to the list */
9849 				add_object_to_objectlist(list, temp_service);
9850 				}
9851 			}
9852 
9853 		/* else this is just a single service... */
9854 		else {
9855 
9856 			/* this service should be excluded (rejected) */
9857 			if(temp_ptr[0] == '!') {
9858 				reject_item = TRUE;
9859 				temp_ptr++;
9860 				}
9861 
9862 #endif
9863 			/* find the service */
9864 			if((temp_service = xodtemplate_find_real_service(host_name, temp_ptr)) != NULL) {
9865 
9866 				found_match = TRUE;
9867 
9868 				if(reject_item == TRUE)
9869 					bitmap_set(reject_map, temp_service->id);
9870 				else
9871 					add_object_to_objectlist(list, temp_service);
9872 			}
9873 #ifndef NSCGI
9874 		}
9875 #endif
9876 		/* we didn't find a match */
9877 		if(found_match == FALSE && reject_item == FALSE) {
9878 			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);
9879 			break;
9880 			}
9881 		}
9882 #ifndef NSCGI
9883 	if(use_regexp_host == TRUE)
9884 		regfree(&preg2);
9885 	my_free(service_names);
9886 #endif
9887 	if(found_match == FALSE && reject_item == FALSE)
9888 		return ERROR;
9889 
9890 	return OK;
9891 	}
9892 
9893 /* returns a comma-delimited list of hostgroup names */
xodtemplate_process_hostgroup_names(char * hostgroups,int _config_file,int _start_line)9894 char * xodtemplate_process_hostgroup_names(char *hostgroups, int _config_file, int _start_line) {
9895 	xodtemplate_memberlist *temp_list = NULL;
9896 	xodtemplate_memberlist *reject_list = NULL;
9897 	xodtemplate_memberlist *list_ptr = NULL;
9898 	xodtemplate_memberlist *reject_ptr = NULL;
9899 	xodtemplate_memberlist *this_list = NULL;
9900 	char *buf = NULL;
9901 	int result = OK;
9902 
9903 	/* process list of hostgroups... */
9904 	if(hostgroups != NULL) {
9905 
9906 		/* split group names into two lists */
9907 		result = xodtemplate_get_hostgroup_names(&temp_list, &reject_list, hostgroups, _config_file, _start_line);
9908 		if(result != OK) {
9909 			xodtemplate_free_memberlist(&temp_list);
9910 			xodtemplate_free_memberlist(&reject_list);
9911 			return NULL;
9912 			}
9913 
9914 		/* remove rejects (if any) from the list (no duplicate entries exist in either list) */
9915 		for(reject_ptr = reject_list; reject_ptr != NULL; reject_ptr = reject_ptr->next) {
9916 			for(list_ptr = temp_list; list_ptr != NULL; list_ptr = list_ptr->next) {
9917 				if(!strcmp(reject_ptr->name1, list_ptr->name1)) {
9918 					xodtemplate_remove_memberlist_item(list_ptr, &temp_list);
9919 					break;
9920 					}
9921 				}
9922 			}
9923 
9924 		xodtemplate_free_memberlist(&reject_list);
9925 		reject_list = NULL;
9926 		}
9927 
9928 	/* generate the list of group members */
9929 	for(this_list = temp_list; this_list != NULL; this_list = this_list->next) {
9930 		if(buf == NULL) {
9931 			buf = (char *)malloc(strlen(this_list->name1) + 1);
9932 			strcpy(buf, this_list->name1);
9933 			}
9934 		else {
9935 			buf = (char *)realloc(buf, strlen(buf) + strlen(this_list->name1) + 2);
9936 			strcat(buf, ",");
9937 			strcat(buf, this_list->name1);
9938 			}
9939 		}
9940 
9941 	xodtemplate_free_memberlist(&temp_list);
9942 
9943 	return buf;
9944 	}
9945 
9946 
9947 
9948 /* 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)9949 int xodtemplate_get_hostgroup_names(xodtemplate_memberlist **list, xodtemplate_memberlist **reject_list, char *hostgroups, int _config_file, int _start_line) {
9950 	char *hostgroup_names = NULL;
9951 	char *temp_ptr = NULL;
9952 	xodtemplate_hostgroup *temp_hostgroup = NULL;
9953 	regex_t preg;
9954 	int found_match = TRUE;
9955 	int reject_item = FALSE;
9956 	int use_regexp = FALSE;
9957 
9958 	if(list == NULL || hostgroups == NULL)
9959 		return ERROR;
9960 
9961 	/* allocate memory for hostgroup name list */
9962 	if((hostgroup_names = (char *)strdup(hostgroups)) == NULL)
9963 		return ERROR;
9964 
9965 	for(temp_ptr = strtok(hostgroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) {
9966 
9967 		found_match = FALSE;
9968 		reject_item = FALSE;
9969 
9970 		/* strip trailing spaces */
9971 		strip(temp_ptr);
9972 
9973 		/* should we use regular expression matching? */
9974 		if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\.")))
9975 			use_regexp = TRUE;
9976 		else
9977 			use_regexp = FALSE;
9978 
9979 		/* use regular expression matching */
9980 		if(use_regexp == TRUE) {
9981 
9982 			/* compile regular expression */
9983 			if(regcomp(&preg, temp_ptr, REG_EXTENDED)) {
9984 				my_free(hostgroup_names);
9985 				return ERROR;
9986 				}
9987 
9988 			/* test match against all hostgroup names */
9989 			for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) {
9990 
9991 				if(temp_hostgroup->hostgroup_name == NULL)
9992 					continue;
9993 
9994 				/* skip this hostgroup if it did not match the expression */
9995 				if(regexec(&preg, temp_hostgroup->hostgroup_name, 0, NULL, 0))
9996 					continue;
9997 
9998 				found_match = TRUE;
9999 
10000 				/* don't add hostgroups that shouldn't be registered */
10001 				if(temp_hostgroup->register_object == FALSE)
10002 					continue;
10003 
10004 				/* add hostgroup to list */
10005 				xodtemplate_add_member_to_memberlist(list, temp_hostgroup->hostgroup_name, NULL);
10006 				}
10007 
10008 			/* free memory allocated to compiled regexp */
10009 			regfree(&preg);
10010 			}
10011 
10012 		/* use standard matching... */
10013 		else {
10014 
10015 			/* return a list of all hostgroups */
10016 			if(!strcmp(temp_ptr, "*")) {
10017 
10018 				found_match = TRUE;
10019 
10020 				for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) {
10021 
10022 					/* don't add hostgroups that shouldn't be registered */
10023 					if(temp_hostgroup->register_object == FALSE)
10024 						continue;
10025 
10026 					/* add hostgroup to list */
10027 					xodtemplate_add_member_to_memberlist(list, temp_hostgroup->hostgroup_name, NULL);
10028 					}
10029 				}
10030 
10031 			/* else this is just a single hostgroup... */
10032 			else {
10033 
10034 				/* this hostgroup should be excluded (rejected) */
10035 				if(temp_ptr[0] == '!') {
10036 					reject_item = TRUE;
10037 					temp_ptr++;
10038 					}
10039 
10040 				/* find the hostgroup */
10041 				temp_hostgroup = xodtemplate_find_real_hostgroup(temp_ptr);
10042 				if(temp_hostgroup != NULL) {
10043 
10044 					found_match = TRUE;
10045 
10046 					/* add hostgroup to proper list */
10047 					xodtemplate_add_member_to_memberlist((reject_item == TRUE) ? reject_list : list, temp_hostgroup->hostgroup_name, NULL);
10048 					}
10049 				}
10050 			}
10051 
10052 		if(found_match == FALSE) {
10053 			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);
10054 			break;
10055 			}
10056 		}
10057 
10058 	/* free memory */
10059 	my_free(hostgroup_names);
10060 
10061 	if(found_match == FALSE)
10062 		return ERROR;
10063 
10064 	return OK;
10065 	}
10066 
10067 
10068 
10069 /* returns a comma-delimited list of contactgroup names */
xodtemplate_process_contactgroup_names(char * contactgroups,int _config_file,int _start_line)10070 char * xodtemplate_process_contactgroup_names(char *contactgroups, int _config_file, int _start_line) {
10071 	xodtemplate_memberlist *temp_list = NULL;
10072 	xodtemplate_memberlist *reject_list = NULL;
10073 	xodtemplate_memberlist *list_ptr = NULL;
10074 	xodtemplate_memberlist *reject_ptr = NULL;
10075 	xodtemplate_memberlist *this_list = NULL;
10076 	char *buf = NULL;
10077 	int result = OK;
10078 
10079 	/* process list of contactgroups... */
10080 	if(contactgroups != NULL) {
10081 
10082 		/* split group names into two lists */
10083 		result = xodtemplate_get_contactgroup_names(&temp_list, &reject_list, contactgroups, _config_file, _start_line);
10084 		if(result != OK) {
10085 			xodtemplate_free_memberlist(&temp_list);
10086 			xodtemplate_free_memberlist(&reject_list);
10087 			return NULL;
10088 			}
10089 
10090 		/* remove rejects (if any) from the list (no duplicate entries exist in either list) */
10091 		for(reject_ptr = reject_list; reject_ptr != NULL; reject_ptr = reject_ptr->next) {
10092 			for(list_ptr = temp_list; list_ptr != NULL; list_ptr = list_ptr->next) {
10093 				if(!strcmp(reject_ptr->name1, list_ptr->name1)) {
10094 					xodtemplate_remove_memberlist_item(list_ptr, &temp_list);
10095 					break;
10096 					}
10097 				}
10098 			}
10099 
10100 		xodtemplate_free_memberlist(&reject_list);
10101 		reject_list = NULL;
10102 		}
10103 
10104 	/* generate the list of group members */
10105 	for(this_list = temp_list; this_list != NULL; this_list = this_list->next) {
10106 		if(buf == NULL) {
10107 			buf = (char *)malloc(strlen(this_list->name1) + 1);
10108 			strcpy(buf, this_list->name1);
10109 			}
10110 		else {
10111 			buf = (char *)realloc(buf, strlen(buf) + strlen(this_list->name1) + 2);
10112 			strcat(buf, ",");
10113 			strcat(buf, this_list->name1);
10114 			}
10115 		}
10116 
10117 	xodtemplate_free_memberlist(&temp_list);
10118 
10119 	return buf;
10120 	}
10121 
10122 
10123 
10124 /* 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)10125 int xodtemplate_get_contactgroup_names(xodtemplate_memberlist **list, xodtemplate_memberlist **reject_list, char *contactgroups, int _config_file, int _start_line) {
10126 	char *contactgroup_names = NULL;
10127 	char *temp_ptr = NULL;
10128 	xodtemplate_contactgroup *temp_contactgroup = NULL;
10129 	regex_t preg;
10130 	int found_match = TRUE;
10131 	int reject_item = FALSE;
10132 	int use_regexp = FALSE;
10133 
10134 	if(list == NULL || contactgroups == NULL)
10135 		return ERROR;
10136 
10137 	/* allocate memory for contactgroup name list */
10138 	if((contactgroup_names = (char *)strdup(contactgroups)) == NULL)
10139 		return ERROR;
10140 
10141 	for(temp_ptr = strtok(contactgroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) {
10142 
10143 		found_match = FALSE;
10144 		reject_item = FALSE;
10145 
10146 		/* strip trailing spaces */
10147 		strip(temp_ptr);
10148 
10149 		/* should we use regular expression matching? */
10150 		if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\.")))
10151 			use_regexp = TRUE;
10152 		else
10153 			use_regexp = FALSE;
10154 
10155 		/* use regular expression matching */
10156 		if(use_regexp == TRUE) {
10157 
10158 			/* compile regular expression */
10159 			if(regcomp(&preg, temp_ptr, REG_EXTENDED)) {
10160 				my_free(contactgroup_names);
10161 				return ERROR;
10162 				}
10163 
10164 			/* test match against all contactgroup names */
10165 			for(temp_contactgroup = xodtemplate_contactgroup_list; temp_contactgroup != NULL; temp_contactgroup = temp_contactgroup->next) {
10166 
10167 				if(temp_contactgroup->contactgroup_name == NULL)
10168 					continue;
10169 
10170 				/* skip this contactgroup if it did not match the expression */
10171 				if(regexec(&preg, temp_contactgroup->contactgroup_name, 0, NULL, 0))
10172 					continue;
10173 
10174 				found_match = TRUE;
10175 
10176 				/* don't add contactgroups that shouldn't be registered */
10177 				if(temp_contactgroup->register_object == FALSE)
10178 					continue;
10179 
10180 				/* add contactgroup to list */
10181 				xodtemplate_add_member_to_memberlist(list, temp_contactgroup->contactgroup_name, NULL);
10182 				}
10183 
10184 			/* free memory allocated to compiled regexp */
10185 			regfree(&preg);
10186 			}
10187 
10188 		/* use standard matching... */
10189 		else {
10190 
10191 			/* return a list of all contactgroups */
10192 			if(!strcmp(temp_ptr, "*")) {
10193 
10194 				found_match = TRUE;
10195 
10196 				for(temp_contactgroup = xodtemplate_contactgroup_list; temp_contactgroup != NULL; temp_contactgroup = temp_contactgroup->next) {
10197 
10198 					/* don't add contactgroups that shouldn't be registered */
10199 					if(temp_contactgroup->register_object == FALSE)
10200 						continue;
10201 
10202 					/* add contactgroup to list */
10203 					xodtemplate_add_member_to_memberlist(list, temp_contactgroup->contactgroup_name, NULL);
10204 					}
10205 				}
10206 
10207 			/* else this is just a single contactgroup... */
10208 			else {
10209 
10210 				/* this contactgroup should be excluded (rejected) */
10211 				if(temp_ptr[0] == '!') {
10212 					reject_item = TRUE;
10213 					temp_ptr++;
10214 					}
10215 
10216 				/* find the contactgroup */
10217 				temp_contactgroup = xodtemplate_find_real_contactgroup(temp_ptr);
10218 				if(temp_contactgroup != NULL) {
10219 
10220 					found_match = TRUE;
10221 
10222 					/* add contactgroup members to proper list */
10223 					xodtemplate_add_member_to_memberlist((reject_item == TRUE) ? reject_list : list, temp_contactgroup->contactgroup_name, NULL);
10224 					}
10225 				}
10226 			}
10227 
10228 		if(found_match == FALSE) {
10229 			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);
10230 			break;
10231 			}
10232 		}
10233 
10234 	/* free memory */
10235 	my_free(contactgroup_names);
10236 
10237 	if(found_match == FALSE)
10238 		return ERROR;
10239 
10240 	return OK;
10241 	}
10242 
10243 
10244 
10245 /* returns a comma-delimited list of servicegroup names */
xodtemplate_process_servicegroup_names(char * servicegroups,int _config_file,int _start_line)10246 char * xodtemplate_process_servicegroup_names(char *servicegroups, int _config_file, int _start_line) {
10247 	xodtemplate_memberlist *temp_list = NULL;
10248 	xodtemplate_memberlist *reject_list = NULL;
10249 	xodtemplate_memberlist *list_ptr = NULL;
10250 	xodtemplate_memberlist *reject_ptr = NULL;
10251 	xodtemplate_memberlist *this_list = NULL;
10252 	char *buf = NULL;
10253 	int result = OK;
10254 
10255 	/* process list of servicegroups... */
10256 	if(servicegroups != NULL) {
10257 
10258 		/* split group names into two lists */
10259 		result = xodtemplate_get_servicegroup_names(&temp_list, &reject_list, servicegroups, _config_file, _start_line);
10260 		if(result != OK) {
10261 			xodtemplate_free_memberlist(&temp_list);
10262 			xodtemplate_free_memberlist(&reject_list);
10263 			return NULL;
10264 			}
10265 
10266 		/* remove rejects (if any) from the list (no duplicate entries exist in either list) */
10267 		for(reject_ptr = reject_list; reject_ptr != NULL; reject_ptr = reject_ptr->next) {
10268 			for(list_ptr = temp_list; list_ptr != NULL; list_ptr = list_ptr->next) {
10269 				if(!strcmp(reject_ptr->name1, list_ptr->name1)) {
10270 					xodtemplate_remove_memberlist_item(list_ptr, &temp_list);
10271 					break;
10272 					}
10273 				}
10274 			}
10275 
10276 		xodtemplate_free_memberlist(&reject_list);
10277 		reject_list = NULL;
10278 		}
10279 
10280 	/* generate the list of group members */
10281 	for(this_list = temp_list; this_list != NULL; this_list = this_list->next) {
10282 		if(buf == NULL) {
10283 			buf = (char *)malloc(strlen(this_list->name1) + 1);
10284 			strcpy(buf, this_list->name1);
10285 			}
10286 		else {
10287 			buf = (char *)realloc(buf, strlen(buf) + strlen(this_list->name1) + 2);
10288 			strcat(buf, ",");
10289 			strcat(buf, this_list->name1);
10290 			}
10291 		}
10292 
10293 	xodtemplate_free_memberlist(&temp_list);
10294 
10295 	return buf;
10296 	}
10297 
10298 
10299 
10300 /* 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)10301 int xodtemplate_get_servicegroup_names(xodtemplate_memberlist **list, xodtemplate_memberlist **reject_list, char *servicegroups, int _config_file, int _start_line) {
10302 	char *servicegroup_names = NULL;
10303 	char *temp_ptr = NULL;
10304 	xodtemplate_servicegroup *temp_servicegroup = NULL;
10305 	regex_t preg;
10306 	int found_match = TRUE;
10307 	int reject_item = FALSE;
10308 	int use_regexp = FALSE;
10309 
10310 	if(list == NULL || servicegroups == NULL)
10311 		return ERROR;
10312 
10313 	/* allocate memory for servicegroup name list */
10314 	if((servicegroup_names = (char *)strdup(servicegroups)) == NULL)
10315 		return ERROR;
10316 
10317 	for(temp_ptr = strtok(servicegroup_names, ","); temp_ptr; temp_ptr = strtok(NULL, ",")) {
10318 
10319 		found_match = FALSE;
10320 		reject_item = FALSE;
10321 
10322 		/* strip trailing spaces */
10323 		strip(temp_ptr);
10324 
10325 		/* should we use regular expression matching? */
10326 		if(use_regexp_matches == TRUE && (use_true_regexp_matching == TRUE || strstr(temp_ptr, "*") || strstr(temp_ptr, "?") || strstr(temp_ptr, "+") || strstr(temp_ptr, "\\.")))
10327 			use_regexp = TRUE;
10328 		else
10329 			use_regexp = FALSE;
10330 
10331 		/* use regular expression matching */
10332 		if(use_regexp == TRUE) {
10333 
10334 			/* compile regular expression */
10335 			if(regcomp(&preg, temp_ptr, REG_EXTENDED)) {
10336 				my_free(servicegroup_names);
10337 				return ERROR;
10338 				}
10339 
10340 			/* test match against all servicegroup names */
10341 			for(temp_servicegroup = xodtemplate_servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) {
10342 
10343 				if(temp_servicegroup->servicegroup_name == NULL)
10344 					continue;
10345 
10346 				/* skip this servicegroup if it did not match the expression */
10347 				if(regexec(&preg, temp_servicegroup->servicegroup_name, 0, NULL, 0))
10348 					continue;
10349 
10350 				found_match = TRUE;
10351 
10352 				/* don't add servicegroups that shouldn't be registered */
10353 				if(temp_servicegroup->register_object == FALSE)
10354 					continue;
10355 
10356 				/* add servicegroup to list */
10357 				xodtemplate_add_member_to_memberlist(list, temp_servicegroup->servicegroup_name, NULL);
10358 				}
10359 
10360 			/* free memory allocated to compiled regexp */
10361 			regfree(&preg);
10362 			}
10363 
10364 		/* use standard matching... */
10365 		else {
10366 
10367 			/* return a list of all servicegroups */
10368 			if(!strcmp(temp_ptr, "*")) {
10369 
10370 				found_match = TRUE;
10371 
10372 				for(temp_servicegroup = xodtemplate_servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) {
10373 
10374 					/* don't add servicegroups that shouldn't be registered */
10375 					if(temp_servicegroup->register_object == FALSE)
10376 						continue;
10377 
10378 					/* add servicegroup to list */
10379 					xodtemplate_add_member_to_memberlist(list, temp_servicegroup->servicegroup_name, NULL);
10380 					}
10381 				}
10382 
10383 			/* else this is just a single servicegroup... */
10384 			else {
10385 
10386 				/* this servicegroup should be excluded (rejected) */
10387 				if(temp_ptr[0] == '!') {
10388 					reject_item = TRUE;
10389 					temp_ptr++;
10390 					}
10391 
10392 				/* find the servicegroup */
10393 				temp_servicegroup = xodtemplate_find_real_servicegroup(temp_ptr);
10394 				if(temp_servicegroup != NULL) {
10395 
10396 					found_match = TRUE;
10397 
10398 					/* add servicegroup members to proper list */
10399 					xodtemplate_add_member_to_memberlist((reject_item == TRUE) ? reject_list : list, temp_servicegroup->servicegroup_name, NULL);
10400 					}
10401 				}
10402 			}
10403 
10404 		if(found_match == FALSE) {
10405 			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);
10406 			break;
10407 			}
10408 		}
10409 
10410 	/* free memory */
10411 	my_free(servicegroup_names);
10412 
10413 	if(found_match == FALSE)
10414 		return ERROR;
10415 
10416 	return OK;
10417 	}
10418 
10419 #ifndef NSCGI
10420 
10421 /******************************************************************/
10422 /****************** ADDITIVE INHERITANCE STUFF ********************/
10423 /******************************************************************/
10424 
10425 /* determines the value of an inherited string */
xodtemplate_get_inherited_string(char * have_template_value,char ** template_value,char * have_this_value,char ** this_value)10426 int xodtemplate_get_inherited_string(char *have_template_value, char **template_value, char *have_this_value, char **this_value) {
10427 	char *buf = NULL;
10428 
10429 	/* template has a value we should use */
10430 	if(*have_template_value == TRUE) {
10431 
10432 		/* template has a non-NULL value */
10433 		if(*template_value != NULL) {
10434 
10435 			/* we have no value... */
10436 			if(*this_value == NULL) {
10437 
10438 				/* use the template value only if we need a value - otherwise stay NULL */
10439 				if(*have_this_value == FALSE) {
10440 					/* NOTE: leave leading + sign if present, as it needed during object resolution and will get stripped later */
10441 					*this_value = (char *)strdup(*template_value);
10442 					}
10443 				}
10444 
10445 			/* we already have a value... */
10446 			else {
10447 				/* our value should be added to the template value */
10448 				if(*this_value[0] == '+') {
10449 					if((buf = (char *)malloc(strlen(*template_value) + strlen(*this_value) + 1))) {
10450 						strcpy(buf, *template_value);
10451 						strcat(buf, ",");
10452 						strcat(buf, *this_value + 1);
10453 						my_free(*this_value);
10454 						*this_value = buf;
10455 						}
10456 					}
10457 
10458 				/* otherwise our value overrides/replaces the template value */
10459 				}
10460 			}
10461 
10462 		/* template has a NULL value.... */
10463 
10464 		*have_this_value = TRUE;
10465 		}
10466 
10467 	return OK;
10468 	}
10469 
10470 
10471 /* removes leading + sign from various directives */
xodtemplate_clean_additive_string(char ** str)10472 int xodtemplate_clean_additive_string(char **str) {
10473 	char *buf = NULL;
10474 
10475 	/* remove the additive symbol if present */
10476 	if(*str != NULL && *str[0] == '+') {
10477 		buf = (char *)strdup(*str + 1);
10478 		my_free(*str);
10479 		*str = buf;
10480 		}
10481 
10482 	return OK;
10483 	}
10484 
10485 
10486 /* cleans strings which may contain additive inheritance directives */
10487 /* NOTE: this must be done after objects are resolved */
xodtemplate_clean_additive_strings(void)10488 int xodtemplate_clean_additive_strings(void) {
10489 	xodtemplate_contactgroup *temp_contactgroup = NULL;
10490 	xodtemplate_hostgroup *temp_hostgroup = NULL;
10491 	xodtemplate_servicegroup *temp_servicegroup = NULL;
10492 	xodtemplate_servicedependency *temp_servicedependency = NULL;
10493 	xodtemplate_serviceescalation *temp_serviceescalation = NULL;
10494 	xodtemplate_contact *temp_contact = NULL;
10495 	xodtemplate_host *temp_host = NULL;
10496 	xodtemplate_service *temp_service = NULL;
10497 	xodtemplate_hostdependency *temp_hostdependency = NULL;
10498 	xodtemplate_hostescalation *temp_hostescalation = NULL;
10499 
10500 	/* resolve all contactgroup objects */
10501 	for(temp_contactgroup = xodtemplate_contactgroup_list; temp_contactgroup != NULL; temp_contactgroup = temp_contactgroup->next) {
10502 		xodtemplate_clean_additive_string(&temp_contactgroup->members);
10503 		xodtemplate_clean_additive_string(&temp_contactgroup->contactgroup_members);
10504 		}
10505 
10506 	/* resolve all hostgroup objects */
10507 	for(temp_hostgroup = xodtemplate_hostgroup_list; temp_hostgroup != NULL; temp_hostgroup = temp_hostgroup->next) {
10508 		xodtemplate_clean_additive_string(&temp_hostgroup->members);
10509 		xodtemplate_clean_additive_string(&temp_hostgroup->hostgroup_members);
10510 		}
10511 
10512 	/* resolve all servicegroup objects */
10513 	for(temp_servicegroup = xodtemplate_servicegroup_list; temp_servicegroup != NULL; temp_servicegroup = temp_servicegroup->next) {
10514 		xodtemplate_clean_additive_string(&temp_servicegroup->members);
10515 		xodtemplate_clean_additive_string(&temp_servicegroup->servicegroup_members);
10516 		}
10517 
10518 	/* resolve all servicedependency objects */
10519 	for(temp_servicedependency = xodtemplate_servicedependency_list; temp_servicedependency != NULL; temp_servicedependency = temp_servicedependency->next) {
10520 		xodtemplate_clean_additive_string(&temp_servicedependency->servicegroup_name);
10521 		xodtemplate_clean_additive_string(&temp_servicedependency->hostgroup_name);
10522 		xodtemplate_clean_additive_string(&temp_servicedependency->host_name);
10523 		xodtemplate_clean_additive_string(&temp_servicedependency->service_description);
10524 		xodtemplate_clean_additive_string(&temp_servicedependency->dependent_servicegroup_name);
10525 		xodtemplate_clean_additive_string(&temp_servicedependency->dependent_hostgroup_name);
10526 		xodtemplate_clean_additive_string(&temp_servicedependency->dependent_host_name);
10527 		xodtemplate_clean_additive_string(&temp_servicedependency->dependent_service_description);
10528 		}
10529 
10530 	/* resolve all serviceescalation objects */
10531 	for(temp_serviceescalation = xodtemplate_serviceescalation_list; temp_serviceescalation != NULL; temp_serviceescalation = temp_serviceescalation->next) {
10532 		/* 03/05/08 some vars are now handled in xodtemplate_inherit_object_properties() */
10533 		/*
10534 		xodtemplate_clean_additive_string(&temp_serviceescalation->contact_groups);
10535 		xodtemplate_clean_additive_string(&temp_serviceescalation->contacts);
10536 		*/
10537 		xodtemplate_clean_additive_string(&temp_serviceescalation->servicegroup_name);
10538 		xodtemplate_clean_additive_string(&temp_serviceescalation->hostgroup_name);
10539 		xodtemplate_clean_additive_string(&temp_serviceescalation->host_name);
10540 		xodtemplate_clean_additive_string(&temp_serviceescalation->service_description);
10541 		}
10542 
10543 	/* resolve all contact objects */
10544 	for(temp_contact = xodtemplate_contact_list; temp_contact != NULL; temp_contact = temp_contact->next) {
10545 		xodtemplate_clean_additive_string(&temp_contact->contact_groups);
10546 		xodtemplate_clean_additive_string(&temp_contact->host_notification_commands);
10547 		xodtemplate_clean_additive_string(&temp_contact->service_notification_commands);
10548 		}
10549 
10550 	/* clean all host objects */
10551 	for(temp_host = xodtemplate_host_list; temp_host != NULL; temp_host = temp_host->next) {
10552 		xodtemplate_clean_additive_string(&temp_host->contact_groups);
10553 		xodtemplate_clean_additive_string(&temp_host->contacts);
10554 		xodtemplate_clean_additive_string(&temp_host->parents);
10555 		xodtemplate_clean_additive_string(&temp_host->host_groups);
10556 		}
10557 
10558 	/* clean all service objects */
10559 	for(temp_service = xodtemplate_service_list; temp_service != NULL; temp_service = temp_service->next) {
10560 		xodtemplate_clean_additive_string(&temp_service->contact_groups);
10561 		xodtemplate_clean_additive_string(&temp_service->contacts);
10562 		xodtemplate_clean_additive_string(&temp_service->host_name);
10563 		xodtemplate_clean_additive_string(&temp_service->hostgroup_name);
10564 		xodtemplate_clean_additive_string(&temp_service->service_groups);
10565 		}
10566 
10567 	/* resolve all hostdependency objects */
10568 	for(temp_hostdependency = xodtemplate_hostdependency_list; temp_hostdependency != NULL; temp_hostdependency = temp_hostdependency->next) {
10569 		xodtemplate_clean_additive_string(&temp_hostdependency->host_name);
10570 		xodtemplate_clean_additive_string(&temp_hostdependency->dependent_host_name);
10571 		xodtemplate_clean_additive_string(&temp_hostdependency->hostgroup_name);
10572 		xodtemplate_clean_additive_string(&temp_hostdependency->dependent_hostgroup_name);
10573 		}
10574 
10575 	/* resolve all hostescalation objects */
10576 	for(temp_hostescalation = xodtemplate_hostescalation_list; temp_hostescalation != NULL; temp_hostescalation = temp_hostescalation->next) {
10577 		/* 03/05/08 some vars are now handled in xodtemplate_inherit_object_properties() */
10578 		/*
10579 		xodtemplate_clean_additive_string(&temp_hostescalation->contact_groups);
10580 		xodtemplate_clean_additive_string(&temp_hostescalation->contacts);
10581 		*/
10582 		xodtemplate_clean_additive_string(&temp_hostescalation->host_name);
10583 		xodtemplate_clean_additive_string(&temp_hostescalation->hostgroup_name);
10584 		}
10585 
10586 	return OK;
10587 	}
10588 
10589 #endif
10590