1 /*****************************************************************************
2 *
3 * OBJECTS.C - Object addition and search functions for Nagios
4 *
5 *
6 * License:
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 *****************************************************************************/
22
23 #include "../include/config.h"
24 #include "../include/common.h"
25 #include "../include/objects.h"
26 #include "../xdata/xodtemplate.h"
27
28 #ifdef NSCGI
29 #include "../include/cgiutils.h"
30 #else
31 #include "../include/nagios.h"
32 #endif
33
34
35
36 /*
37 * These get created in xdata/xodtemplate.c:xodtemplate_register_objects()
38 * Escalations are attached to the objects they belong to.
39 * Dependencies are attached to the dependent end of the object chain.
40 */
41 dkhash_table *object_hash_tables[NUM_OBJECT_SKIPLISTS];
42
43 command *command_list = NULL;
44 timeperiod *timeperiod_list = NULL;
45 host *host_list = NULL;
46 service *service_list = NULL;
47 contact *contact_list = NULL;
48 hostgroup *hostgroup_list = NULL;
49 servicegroup *servicegroup_list = NULL;
50 contactgroup *contactgroup_list = NULL;
51 hostescalation *hostescalation_list = NULL;
52 serviceescalation *serviceescalation_list = NULL;
53 command **command_ary = NULL;
54 timeperiod **timeperiod_ary = NULL;
55 host **host_ary = NULL;
56 service **service_ary = NULL;
57 contact **contact_ary = NULL;
58 hostgroup **hostgroup_ary = NULL;
59 servicegroup **servicegroup_ary = NULL;
60 contactgroup **contactgroup_ary = NULL;
61 hostescalation **hostescalation_ary = NULL;
62 serviceescalation **serviceescalation_ary = NULL;
63 hostdependency **hostdependency_ary = NULL;
64 servicedependency **servicedependency_ary = NULL;
65
66 #ifndef NSCGI
67 int __nagios_object_structure_version = CURRENT_OBJECT_STRUCTURE_VERSION;
68
69 struct flag_map {
70 int opt;
71 int ch;
72 const char *name;
73 };
74
75 static const struct flag_map service_flag_map[] = {
76 { OPT_WARNING, 'w', "warning" },
77 { OPT_UNKNOWN, 'u', "unknown" },
78 { OPT_CRITICAL, 'c', "critical" },
79 { OPT_FLAPPING, 'f', "flapping" },
80 { OPT_DOWNTIME, 's', "downtime" },
81 { OPT_OK, 'o', "ok" },
82 { OPT_RECOVERY, 'r', "recovery" },
83 { OPT_PENDING, 'p', "pending" },
84 { OPT_NOTIFICATIONS, 'N', "notifications" },
85 { 0, 0, NULL },
86 };
87
88 static const struct flag_map host_flag_map[] = {
89 { OPT_DOWN, 'd', "down" },
90 { OPT_UNREACHABLE, 'u', "unreachable" },
91 { OPT_FLAPPING, 'f', "flapping" },
92 { OPT_RECOVERY, 'r', "recovery" },
93 { OPT_DOWNTIME, 's', "downtime" },
94 { OPT_PENDING, 'p', "pending" },
95 { OPT_NOTIFICATIONS, 'N', "notifications" },
96 { 0, 0, NULL },
97 };
98
opts2str(int opts,const struct flag_map * map,char ok_char)99 static const char *opts2str(int opts, const struct flag_map *map, char ok_char)
100 {
101 int i, pos = 0;
102 static char buf[16];
103
104 if(!opts)
105 return "n";
106
107 if(opts == OPT_ALL)
108 return "a";
109
110 if(flag_isset(opts, OPT_OK)) {
111 flag_unset(opts, OPT_OK);
112 buf[pos++] = ok_char;
113 buf[pos++] = opts ? ',' : 0;
114 }
115
116 for (i = 0; map[i].name; i++) {
117 if(flag_isset(opts, map[i].opt)) {
118 buf[pos++] = map[i].ch;
119 flag_unset(opts, map[i].opt);
120 if(!opts)
121 break;
122 buf[pos++] = ',';
123 }
124 }
125 buf[pos++] = 0;
126 return buf;
127 }
128 #endif
129
host_services_value(host * h)130 unsigned int host_services_value(host *h) {
131 servicesmember *sm;
132 unsigned int ret = 0;
133 for(sm = h->services; sm; sm = sm->next) {
134 ret += sm->service_ptr->hourly_value;
135 }
136 return ret;
137 }
138
139
140 #ifndef NSCGI
141 /* Host/Service dependencies are not visible in Nagios CGIs, so we exclude them */
cmp_sdep(const void * a_,const void * b_)142 static int cmp_sdep(const void *a_, const void *b_) {
143 const servicedependency *a = *(servicedependency **)a_;
144 const servicedependency *b = *(servicedependency **)b_;
145 int ret;
146 ret = a->master_service_ptr->id - b->master_service_ptr->id;
147 return ret ? ret : (int)(a->dependent_service_ptr->id - b->dependent_service_ptr->id);
148 }
149
cmp_hdep(const void * a_,const void * b_)150 static int cmp_hdep(const void *a_, const void *b_) {
151 const hostdependency *a = *(const hostdependency **)a_;
152 const hostdependency *b = *(const hostdependency **)b_;
153 int ret;
154 ret = a->master_host_ptr->id - b->master_host_ptr->id;
155 return ret ? ret : (int)(a->dependent_host_ptr->id - b->dependent_host_ptr->id);
156 }
157
cmp_serviceesc(const void * a_,const void * b_)158 static int cmp_serviceesc(const void *a_, const void *b_) {
159 const serviceescalation *a = *(const serviceescalation **)a_;
160 const serviceescalation *b = *(const serviceescalation **)b_;
161 return a->service_ptr->id - b->service_ptr->id;
162 }
163
cmp_hostesc(const void * a_,const void * b_)164 static int cmp_hostesc(const void *a_, const void *b_) {
165 const hostescalation *a = *(const hostescalation **)a_;
166 const hostescalation *b = *(const hostescalation **)b_;
167 return a->host_ptr->id - b->host_ptr->id;
168 }
169 #endif
170
post_process_object_config(void)171 static void post_process_object_config(void) {
172 objectlist *list;
173 unsigned int i, slot;
174
175 if(hostdependency_ary)
176 free(hostdependency_ary);
177 if(servicedependency_ary)
178 free(servicedependency_ary);
179
180 hostdependency_ary = calloc(num_objects.hostdependencies, sizeof(void *));
181 servicedependency_ary = calloc(num_objects.servicedependencies, sizeof(void *));
182
183 slot = 0;
184 for(i = 0; slot < num_objects.servicedependencies && i < num_objects.services; i++) {
185 service *s = service_ary[i];
186 for(list = s->notify_deps; list; list = list->next)
187 servicedependency_ary[slot++] = (servicedependency *)list->object_ptr;
188 for(list = s->exec_deps; list; list = list->next)
189 servicedependency_ary[slot++] = (servicedependency *)list->object_ptr;
190 }
191 timing_point("Done post-processing servicedependencies\n");
192
193 slot = 0;
194 for(i = 0; slot < num_objects.hostdependencies && i < num_objects.hosts; i++) {
195 host *h = host_ary[i];
196 for(list = h->notify_deps; list; list = list->next)
197 hostdependency_ary[slot++] = (hostdependency *)list->object_ptr;
198 for(list = h->exec_deps; list; list = list->next)
199 hostdependency_ary[slot++] = (hostdependency *)list->object_ptr;
200 }
201 timing_point("Done post-processing host dependencies\n");
202
203 #ifndef NSCGI
204 /* cgi's always get their objects in sorted order */
205 if(servicedependency_ary)
206 qsort(servicedependency_ary, num_objects.servicedependencies, sizeof(servicedependency *), cmp_sdep);
207 if(hostdependency_ary)
208 qsort(hostdependency_ary, num_objects.hostdependencies, sizeof(hostdependency *), cmp_hdep);
209 if(hostescalation_ary)
210 qsort(hostescalation_ary, num_objects.hostescalations, sizeof(hostescalation *), cmp_hostesc);
211 if(serviceescalation_ary)
212 qsort(serviceescalation_ary, num_objects.serviceescalations, sizeof(serviceescalation *), cmp_serviceesc);
213 timing_point("Done post-sorting slave objects\n");
214 #endif
215
216 timeperiod_list = timeperiod_ary ? *timeperiod_ary : NULL;
217 command_list = command_ary ? *command_ary : NULL;
218 hostgroup_list = hostgroup_ary ? *hostgroup_ary : NULL;
219 contactgroup_list = contactgroup_ary ? *contactgroup_ary : NULL;
220 servicegroup_list = servicegroup_ary ? *servicegroup_ary : NULL;
221 contact_list = contact_ary ? *contact_ary : NULL;
222 host_list = host_ary ? *host_ary : NULL;
223 service_list = service_ary ? *service_ary : NULL;
224 hostescalation_list = hostescalation_ary ? *hostescalation_ary : NULL;
225 serviceescalation_list = serviceescalation_ary ? *serviceescalation_ary : NULL;
226 }
227
228 /* simple state-name helpers, nifty to have all over the place */
service_state_name(int state)229 const char *service_state_name(int state)
230 {
231 switch (state) {
232 case STATE_OK: return "OK";
233 case STATE_WARNING: return "WARNING";
234 case STATE_CRITICAL: return "CRITICAL";
235 }
236
237 return "UNKNOWN";
238 }
239
host_state_name(int state)240 const char *host_state_name(int state)
241 {
242 switch (state) {
243 case HOST_UP: return "UP";
244 case HOST_DOWN: return "DOWN";
245 case HOST_UNREACHABLE: return "UNREACHABLE";
246 }
247
248 return "(unknown)";
249 }
250
state_type_name(int state_type)251 const char *state_type_name(int state_type)
252 {
253 return state_type == HARD_STATE ? "HARD" : "SOFT";
254 }
255
check_type_name(int check_type)256 const char *check_type_name(int check_type)
257 {
258 return check_type == CHECK_TYPE_PASSIVE ? "PASSIVE" : "ACTIVE";
259 }
260
261 /******************************************************************/
262 /******* TOP-LEVEL HOST CONFIGURATION DATA INPUT FUNCTION *********/
263 /******************************************************************/
264
265
266 /* read all host configuration data from external source */
read_object_config_data(const char * main_config_file,int options)267 int read_object_config_data(const char *main_config_file, int options) {
268 int result = OK;
269
270 /* reset object counts */
271 memset(&num_objects, 0, sizeof(num_objects));
272
273 /* read in data from all text host config files (template-based) */
274 result = xodtemplate_read_config_data(main_config_file, options);
275 if(result != OK)
276 return ERROR;
277
278 /* handle any remaining config mangling */
279 post_process_object_config();
280 timing_point("Done post-processing configuration\n");
281
282 return result;
283 }
284
285
286
287 /******************************************************************/
288 /******************** SKIPLIST FUNCTIONS **************************/
289 /******************************************************************/
290
291
skiplist_compare_text(const char * val1a,const char * val1b,const char * val2a,const char * val2b)292 int skiplist_compare_text(const char *val1a, const char *val1b, const char *val2a, const char *val2b) {
293 int result = 0;
294
295 /* check first name */
296 if(val1a == NULL && val2a == NULL)
297 result = 0;
298 else if(val1a == NULL)
299 result = 1;
300 else if(val2a == NULL)
301 result = -1;
302 else
303 result = strcmp(val1a, val2a);
304
305 /* check second name if necessary */
306 if(result == 0) {
307 if(val1b == NULL && val2b == NULL)
308 result = 0;
309 else if(val1b == NULL)
310 result = 1;
311 else if(val2b == NULL)
312 result = -1;
313 else
314 result = strcmp(val1b, val2b);
315 }
316
317 return result;
318 }
319
320
get_host_count(void)321 int get_host_count(void) {
322 return num_objects.hosts;
323 }
324
325
get_service_count(void)326 int get_service_count(void) {
327 return num_objects.services;
328 }
329
330
331
332
333 /******************************************************************/
334 /**************** OBJECT ADDITION FUNCTIONS ***********************/
335 /******************************************************************/
336
create_object_table(const char * name,unsigned int elems,unsigned int size,void ** ptr)337 static int create_object_table(const char *name, unsigned int elems, unsigned int size, void **ptr)
338 {
339 void *ret;
340 if (!elems) {
341 *ptr = NULL;
342 return OK;
343 }
344 ret = calloc(elems, size);
345 if (!ret) {
346 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Failed to allocate %s table with %u elements\n", name, elems);
347 return ERROR;
348 }
349 *ptr = ret;
350 return OK;
351 }
352
353 #define mktable(name, id) \
354 create_object_table(#name, ocount[id], sizeof(name *), (void **)&name##_ary)
355
356 /* ocount is an array with NUM_OBJECT_TYPES members */
create_object_tables(unsigned int * ocount)357 int create_object_tables(unsigned int *ocount)
358 {
359 int i;
360
361 for (i = 0; i < NUM_HASHED_OBJECT_TYPES; i++) {
362 const unsigned int hash_size = ocount[i];
363 if (!hash_size)
364 continue;
365 object_hash_tables[i] = dkhash_create(hash_size);
366 if (!object_hash_tables[i]) {
367 logit(NSLOG_CONFIG_ERROR, TRUE, "Failed to create hash table with %u entries\n", hash_size);
368 }
369 }
370
371 /*
372 * errors here will always lead to an early exit, so there's no need
373 * to free() successful allocs when later ones fail
374 */
375 if (mktable(timeperiod, TIMEPERIOD_SKIPLIST) != OK)
376 return ERROR;
377 if (mktable(command, COMMAND_SKIPLIST) != OK)
378 return ERROR;
379 if (mktable(host, HOST_SKIPLIST) != OK)
380 return ERROR;
381 if (mktable(service, SERVICE_SKIPLIST) != OK)
382 return ERROR;
383 if (mktable(contact, CONTACT_SKIPLIST) != OK)
384 return ERROR;
385 if (mktable(hostgroup, HOSTGROUP_SKIPLIST) != OK)
386 return ERROR;
387 if (mktable(servicegroup, SERVICEGROUP_SKIPLIST) != OK)
388 return ERROR;
389 if (mktable(contactgroup, CONTACTGROUP_SKIPLIST) != OK)
390 return ERROR;
391 if (mktable(hostescalation, HOSTESCALATION_SKIPLIST) != OK)
392 return ERROR;
393 if (mktable(hostdependency, HOSTDEPENDENCY_SKIPLIST) != OK)
394 return ERROR;
395 if (mktable(serviceescalation, SERVICEESCALATION_SKIPLIST) != OK)
396 return ERROR;
397 if (mktable(servicedependency, SERVICEDEPENDENCY_SKIPLIST) != OK)
398 return ERROR;
399
400 return OK;
401 }
402
403
404 /* add a new timeperiod to the list in memory */
add_timeperiod(char * name,char * alias)405 timeperiod *add_timeperiod(char *name, char *alias) {
406 timeperiod *new_timeperiod = NULL;
407 int result = OK;
408
409 /* make sure we have the data we need */
410 if((name == NULL || !strcmp(name, "")) || (alias == NULL || !strcmp(alias, ""))) {
411 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Name or alias for timeperiod is NULL\n");
412 return NULL;
413 }
414
415 new_timeperiod = calloc(1, sizeof(*new_timeperiod));
416 if(!new_timeperiod)
417 return NULL;
418
419 /* copy string vars */
420 new_timeperiod->name = name;
421 new_timeperiod->alias = alias ? alias : name;
422
423 /* add new timeperiod to hash table */
424 if(result == OK) {
425 result = dkhash_insert(object_hash_tables[TIMEPERIOD_SKIPLIST], new_timeperiod->name, NULL, new_timeperiod);
426 switch(result) {
427 case DKHASH_EDUPE:
428 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Timeperiod '%s' has already been defined\n", name);
429 result = ERROR;
430 break;
431 case DKHASH_OK:
432 result = OK;
433 break;
434 default:
435 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add timeperiod '%s' to hash table\n", name);
436 result = ERROR;
437 break;
438 }
439 }
440
441 /* handle errors */
442 if(result == ERROR) {
443 free(new_timeperiod);
444 return NULL;
445 }
446
447 new_timeperiod->id = num_objects.timeperiods++;
448 if(new_timeperiod->id)
449 timeperiod_ary[new_timeperiod->id - 1]->next = new_timeperiod;
450 timeperiod_ary[new_timeperiod->id] = new_timeperiod;
451 return new_timeperiod;
452 }
453
454
455
456
457 /* adds a new exclusion to a timeperiod */
add_exclusion_to_timeperiod(timeperiod * period,char * name)458 timeperiodexclusion *add_exclusion_to_timeperiod(timeperiod *period, char *name) {
459 timeperiodexclusion *new_timeperiodexclusion = NULL;
460
461 /* make sure we have enough data */
462 if(period == NULL || name == NULL)
463 return NULL;
464
465 if((new_timeperiodexclusion = (timeperiodexclusion *)malloc(sizeof(timeperiodexclusion))) == NULL)
466 return NULL;
467
468 new_timeperiodexclusion->timeperiod_name = (char *)strdup(name);
469
470 new_timeperiodexclusion->next = period->exclusions;
471 period->exclusions = new_timeperiodexclusion;
472
473 return new_timeperiodexclusion;
474 }
475
476
477
478
479 /* add a new timerange to a timeperiod */
add_timerange_to_timeperiod(timeperiod * period,int day,unsigned long start_time,unsigned long end_time)480 timerange *add_timerange_to_timeperiod(timeperiod *period, int day, unsigned long start_time, unsigned long end_time) {
481 timerange *prev = NULL, *tr, *new_timerange = NULL;
482
483 /* make sure we have the data we need */
484 if(period == NULL)
485 return NULL;
486
487 if(day < 0 || day > 6) {
488 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Day %d is not valid for timeperiod '%s'\n", day, period->name);
489 return NULL;
490 }
491 if(start_time > 86400) {
492 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Start time %lu on day %d is not valid for timeperiod '%s'\n", start_time, day, period->name);
493 return NULL;
494 }
495 if(end_time > 86400) {
496 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: End time %lu on day %d is not value for timeperiod '%s'\n", end_time, day, period->name);
497 return NULL;
498 }
499
500 /* allocate memory for the new time range */
501 if((new_timerange = malloc(sizeof(timerange))) == NULL)
502 return NULL;
503
504 new_timerange->range_start = start_time;
505 new_timerange->range_end = end_time;
506
507 /* insertion-sort the new time range into the list for this day */
508 if(!period->days[day] || period->days[day]->range_start > new_timerange->range_start) {
509 new_timerange->next = period->days[day];
510 period->days[day] = new_timerange;
511 return new_timerange;
512 }
513
514 for(tr = period->days[day]; tr; tr = tr->next) {
515 if(new_timerange->range_start < tr->range_start) {
516 new_timerange->next = tr;
517 prev->next = new_timerange;
518 break;
519 }
520 if(!tr->next) {
521 tr->next = new_timerange;
522 new_timerange->next = NULL;
523 break;
524 }
525 prev = tr;
526 }
527
528 return new_timerange;
529 }
530
531
532 /* add a new exception to a timeperiod */
add_exception_to_timeperiod(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)533 daterange *add_exception_to_timeperiod(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) {
534 daterange *new_daterange = NULL;
535
536 /* make sure we have the data we need */
537 if(period == NULL)
538 return NULL;
539
540 /* allocate memory for the date range range */
541 if((new_daterange = malloc(sizeof(daterange))) == NULL)
542 return NULL;
543
544 new_daterange->times = NULL;
545 new_daterange->next = NULL;
546
547 new_daterange->type = type;
548 new_daterange->syear = syear;
549 new_daterange->smon = smon;
550 new_daterange->smday = smday;
551 new_daterange->swday = swday;
552 new_daterange->swday_offset = swday_offset;
553 new_daterange->eyear = eyear;
554 new_daterange->emon = emon;
555 new_daterange->emday = emday;
556 new_daterange->ewday = ewday;
557 new_daterange->ewday_offset = ewday_offset;
558 new_daterange->skip_interval = skip_interval;
559
560 /* add the new date range to the head of the range list for this exception type */
561 new_daterange->next = period->exceptions[type];
562 period->exceptions[type] = new_daterange;
563
564 return new_daterange;
565 }
566
567
568
569 /* add a new timerange to a daterange */
add_timerange_to_daterange(daterange * drange,unsigned long start_time,unsigned long end_time)570 timerange *add_timerange_to_daterange(daterange *drange, unsigned long start_time, unsigned long end_time) {
571 timerange *new_timerange = NULL;
572
573 /* make sure we have the data we need */
574 if(drange == NULL)
575 return NULL;
576
577 if(start_time > 86400) {
578 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Start time %lu is not valid for timeperiod\n", start_time);
579 return NULL;
580 }
581 if(end_time > 86400) {
582 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: End time %lu is not value for timeperiod\n", end_time);
583 return NULL;
584 }
585
586 /* allocate memory for the new time range */
587 if((new_timerange = malloc(sizeof(timerange))) == NULL)
588 return NULL;
589
590 new_timerange->range_start = start_time;
591 new_timerange->range_end = end_time;
592
593 /* add the new time range to the head of the range list for this date range */
594 new_timerange->next = drange->times;
595 drange->times = new_timerange;
596
597 return new_timerange;
598 }
599
600
601
602 /* add a new host definition */
add_host(char * name,char * display_name,char * alias,char * address,char * check_period,int initial_state,double check_interval,double retry_interval,int max_attempts,int notification_options,double notification_interval,double first_notification_delay,char * notification_period,int notifications_enabled,char * check_command,int checks_enabled,int accept_passive_checks,char * event_handler,int event_handler_enabled,int flap_detection_enabled,double low_flap_threshold,double high_flap_threshold,int flap_detection_options,int stalking_options,int process_perfdata,int check_freshness,int freshness_threshold,char * notes,char * notes_url,char * action_url,char * icon_image,char * icon_image_alt,char * vrml_image,char * statusmap_image,int x_2d,int y_2d,int have_2d_coords,double x_3d,double y_3d,double z_3d,int have_3d_coords,int should_be_drawn,int retain_status_information,int retain_nonstatus_information,int obsess,unsigned int hourly_value)603 host *add_host(char *name, char *display_name, char *alias, char *address, char *check_period, int initial_state, double check_interval, double retry_interval, int max_attempts, int notification_options, double notification_interval, double first_notification_delay, char *notification_period, int notifications_enabled, char *check_command, int checks_enabled, int accept_passive_checks, char *event_handler, int event_handler_enabled, int flap_detection_enabled, double low_flap_threshold, double high_flap_threshold, int flap_detection_options, int stalking_options, int process_perfdata, int check_freshness, int freshness_threshold, char *notes, char *notes_url, char *action_url, char *icon_image, char *icon_image_alt, char *vrml_image, char *statusmap_image, int x_2d, int y_2d, int have_2d_coords, double x_3d, double y_3d, double z_3d, int have_3d_coords, int should_be_drawn, int retain_status_information, int retain_nonstatus_information, int obsess, unsigned int hourly_value) {
604 host *new_host = NULL;
605 timeperiod *check_tp = NULL, *notify_tp = NULL;
606 int result = OK;
607
608 /* make sure we have the data we need */
609 if(name == NULL || !strcmp(name, "")) {
610 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Host name is NULL\n");
611 return NULL;
612 }
613
614 if(check_period && !(check_tp = find_timeperiod(check_period))) {
615 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Failed to locate check_period '%s' for host '%s'!\n",
616 check_period, name);
617 return NULL;
618 }
619 if(notification_period && !(notify_tp = find_timeperiod(notification_period))) {
620 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Failed to locate notification_period '%s' for host '%s'!\n",
621 notification_period, name);
622 return NULL;
623 }
624 /* check values */
625 if(max_attempts <= 0) {
626 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid max_check_attempts value for host '%s'\n", name);
627 return NULL;
628 }
629 if(check_interval < 0) {
630 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid check_interval value for host '%s'\n", name);
631 return NULL;
632 }
633 if(notification_interval < 0) {
634 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid notification_interval value for host '%s'\n", name);
635 return NULL;
636 }
637 if(first_notification_delay < 0) {
638 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid first_notification_delay value for host '%s'\n", name);
639 return NULL;
640 }
641 if(freshness_threshold < 0) {
642 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid freshness_threshold value for host '%s'\n", name);
643 return NULL;
644 }
645
646 new_host = calloc(1, sizeof(*new_host));
647
648 /* assign string vars */
649 new_host->name = name;
650 new_host->display_name = display_name ? display_name : new_host->name;
651 new_host->alias = alias ? alias : new_host->name;
652 new_host->address = address ? address : new_host->name;
653 new_host->check_period = check_tp ? (char *)strdup(check_tp->name) : NULL;
654 new_host->notification_period = notify_tp ? (char *)strdup(notify_tp->name) : NULL;
655 new_host->notification_period_ptr = notify_tp;
656 new_host->check_period_ptr = check_tp;
657 new_host->check_command = check_command;
658 new_host->event_handler = event_handler;
659 new_host->notes = notes;
660 new_host->notes_url = notes_url;
661 new_host->action_url = action_url;
662 new_host->icon_image = icon_image;
663 new_host->icon_image_alt = icon_image_alt;
664 new_host->vrml_image = vrml_image;
665 new_host->statusmap_image = statusmap_image;
666
667 /* duplicate non-string vars */
668 new_host->hourly_value = hourly_value;
669 new_host->max_attempts = max_attempts;
670 new_host->check_interval = check_interval;
671 new_host->retry_interval = retry_interval;
672 new_host->notification_interval = notification_interval;
673 new_host->first_notification_delay = first_notification_delay;
674 new_host->notification_options = notification_options;
675 new_host->flap_detection_enabled = (flap_detection_enabled > 0) ? TRUE : FALSE;
676 new_host->low_flap_threshold = low_flap_threshold;
677 new_host->high_flap_threshold = high_flap_threshold;
678 new_host->flap_detection_options = flap_detection_options;
679 new_host->stalking_options = stalking_options;
680 new_host->process_performance_data = (process_perfdata > 0) ? TRUE : FALSE;
681 new_host->check_freshness = (check_freshness > 0) ? TRUE : FALSE;
682 new_host->freshness_threshold = freshness_threshold;
683 new_host->checks_enabled = (checks_enabled > 0) ? TRUE : FALSE;
684 new_host->accept_passive_checks = (accept_passive_checks > 0) ? TRUE : FALSE;
685 new_host->event_handler_enabled = (event_handler_enabled > 0) ? TRUE : FALSE;
686 new_host->x_2d = x_2d;
687 new_host->y_2d = y_2d;
688 new_host->have_2d_coords = (have_2d_coords > 0) ? TRUE : FALSE;
689 new_host->x_3d = x_3d;
690 new_host->y_3d = y_3d;
691 new_host->z_3d = z_3d;
692 new_host->have_3d_coords = (have_3d_coords > 0) ? TRUE : FALSE;
693 new_host->should_be_drawn = (should_be_drawn > 0) ? TRUE : FALSE;
694 new_host->obsess = (obsess > 0) ? TRUE : FALSE;
695 new_host->retain_status_information = (retain_status_information > 0) ? TRUE : FALSE;
696 new_host->retain_nonstatus_information = (retain_nonstatus_information > 0) ? TRUE : FALSE;
697 #ifdef NSCORE
698 new_host->current_state = initial_state;
699 new_host->last_state = initial_state;
700 new_host->last_hard_state = initial_state;
701 new_host->check_type = CHECK_TYPE_ACTIVE;
702 new_host->should_be_scheduled = TRUE;
703 new_host->current_attempt = (initial_state == HOST_UP) ? 1 : max_attempts;
704 new_host->state_type = HARD_STATE;
705 new_host->acknowledgement_type = ACKNOWLEDGEMENT_NONE;
706 new_host->notifications_enabled = (notifications_enabled > 0) ? TRUE : FALSE;
707 new_host->check_options = CHECK_OPTION_NONE;
708 #endif
709
710 /* add new host to hash table */
711 if(result == OK) {
712 result = dkhash_insert(object_hash_tables[HOST_SKIPLIST], new_host->name, NULL, new_host);
713 switch(result) {
714 case DKHASH_EDUPE:
715 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Host '%s' has already been defined\n", name);
716 result = ERROR;
717 break;
718 case DKHASH_OK:
719 result = OK;
720 break;
721 default:
722 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add host '%s' to hash table\n", name);
723 result = ERROR;
724 break;
725 }
726 }
727
728 /* handle errors */
729 if(result == ERROR) {
730 my_free(new_host);
731 return NULL;
732 }
733
734 new_host->id = num_objects.hosts++;
735 host_ary[new_host->id] = new_host;
736 if(new_host->id)
737 host_ary[new_host->id - 1]->next = new_host;
738 return new_host;
739 }
740
741
742
add_parent_host_to_host(host * hst,char * host_name)743 hostsmember *add_parent_host_to_host(host *hst, char *host_name) {
744 hostsmember *new_hostsmember = NULL;
745 int result = OK;
746
747 /* make sure we have the data we need */
748 if(hst == NULL || host_name == NULL || !strcmp(host_name, "")) {
749 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Host is NULL or parent host name is NULL\n");
750 return NULL;
751 }
752
753 /* a host cannot be a parent/child of itself */
754 if(!strcmp(host_name, hst->name)) {
755 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Host '%s' cannot be a child/parent of itself\n", hst->name);
756 return NULL;
757 }
758
759 /* allocate memory */
760 if((new_hostsmember = (hostsmember *)calloc(1, sizeof(hostsmember))) == NULL)
761 return NULL;
762
763 /* duplicate string vars */
764 if((new_hostsmember->host_name = (char *)strdup(host_name)) == NULL)
765 result = ERROR;
766
767 /* handle errors */
768 if(result == ERROR) {
769 my_free(new_hostsmember->host_name);
770 my_free(new_hostsmember);
771 return NULL;
772 }
773
774 /* add the parent host entry to the host definition */
775 new_hostsmember->next = hst->parent_hosts;
776 hst->parent_hosts = new_hostsmember;
777
778 return new_hostsmember;
779 }
780
add_parent_service_to_service(service * svc,char * host_name,char * description)781 servicesmember *add_parent_service_to_service(service *svc, char *host_name, char *description) {
782 servicesmember *sm;
783
784 if(!svc || !host_name || !description || !*host_name || !*description)
785 return NULL;
786
787 if (strcmp(svc->host_name, host_name) == 0 && strcmp(svc->description, description) == 0) {
788 logit(NSLOG_CONFIG_ERROR, TRUE,
789 "Error: Host '%s' Service '%s' cannot be a child/parent of itself\n",
790 svc->host_name, svc->description);
791 return NULL;
792 }
793
794 if((sm = calloc(1, sizeof(*sm))) == NULL)
795 return NULL;
796
797 if ((sm->host_name = strdup(host_name)) == NULL || (sm->service_description = strdup(description)) == NULL) {
798 /* there was an error copying (description is NULL now) */
799 my_free(sm->host_name);
800 free(sm);
801 return NULL;
802 }
803
804 sm->next = svc->parents;
805 svc->parents = sm;
806 return sm;
807 }
808
add_child_link_to_host(host * hst,host * child_ptr)809 hostsmember *add_child_link_to_host(host *hst, host *child_ptr) {
810 hostsmember *new_hostsmember = NULL;
811
812 /* make sure we have the data we need */
813 if(hst == NULL || child_ptr == NULL)
814 return NULL;
815
816 /* allocate memory */
817 if((new_hostsmember = (hostsmember *)malloc(sizeof(hostsmember))) == NULL)
818 return NULL;
819
820 /* assign values */
821 new_hostsmember->host_name = child_ptr->name;
822 new_hostsmember->host_ptr = child_ptr;
823
824 /* add the child entry to the host definition */
825 new_hostsmember->next = hst->child_hosts;
826 hst->child_hosts = new_hostsmember;
827
828 return new_hostsmember;
829 }
830
831
832
add_service_link_to_host(host * hst,service * service_ptr)833 servicesmember *add_service_link_to_host(host *hst, service *service_ptr) {
834 servicesmember *new_servicesmember = NULL;
835
836 /* make sure we have the data we need */
837 if(hst == NULL || service_ptr == NULL)
838 return NULL;
839
840 /* allocate memory */
841 if((new_servicesmember = (servicesmember *)calloc(1, sizeof(servicesmember))) == NULL)
842 return NULL;
843
844 /* assign values */
845 new_servicesmember->host_name = service_ptr->host_name;
846 new_servicesmember->service_description = service_ptr->description;
847 new_servicesmember->service_ptr = service_ptr;
848 #ifndef NSCGI
849 hst->total_services++;
850 #endif
851
852 /* add the child entry to the host definition */
853 new_servicesmember->next = hst->services;
854 hst->services = new_servicesmember;
855
856 return new_servicesmember;
857 }
858
859
860
add_child_link_to_service(service * svc,service * child_ptr)861 servicesmember *add_child_link_to_service(service *svc, service *child_ptr) {
862 servicesmember *new_servicesmember = NULL;
863
864 /* make sure we have the data we need */
865 if(svc == NULL || child_ptr == NULL)
866 return NULL;
867
868 /* allocate memory */
869 if((new_servicesmember = (servicesmember *)malloc(sizeof(servicesmember)))
870 == NULL) return NULL;
871
872 /* assign values */
873 new_servicesmember->host_name = child_ptr->host_name;
874 new_servicesmember->service_description = child_ptr->description;
875 new_servicesmember->service_ptr = child_ptr;
876
877 /* add the child entry to the host definition */
878 new_servicesmember->next = svc->children;
879 svc->children = new_servicesmember;
880
881 return new_servicesmember;
882 }
883
884
885
add_contactgroup_to_object(contactgroupsmember ** cg_list,const char * group_name)886 static contactgroupsmember *add_contactgroup_to_object(contactgroupsmember **cg_list, const char *group_name) {
887 contactgroupsmember *cgm;
888 contactgroup *cg;
889
890 if(!group_name || !*group_name) {
891 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Contact name is NULL\n");
892 return NULL;
893 }
894 if(!(cg = find_contactgroup(group_name))) {
895 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Contactgroup '%s' is not defined anywhere\n", group_name);
896 return NULL;
897 }
898 if(!(cgm = malloc(sizeof(*cgm)))) {
899 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not allocate memory for contactgroup\n");
900 return NULL;
901 }
902 cgm->group_name = cg->group_name;
903 cgm->group_ptr = cg;
904 cgm->next = *cg_list;
905 *cg_list = cgm;
906
907 return cgm;
908 }
909
910
911 /* add a new contactgroup to a host */
add_contactgroup_to_host(host * hst,char * group_name)912 contactgroupsmember *add_contactgroup_to_host(host *hst, char *group_name) {
913 return add_contactgroup_to_object(&hst->contact_groups, group_name);
914 }
915
916
917
918 /* adds a contact to a host */
add_contact_to_host(host * hst,char * contact_name)919 contactsmember *add_contact_to_host(host *hst, char *contact_name) {
920
921 return add_contact_to_object(&hst->contacts, contact_name);
922 }
923
924
925
926 /* adds a custom variable to a host */
add_custom_variable_to_host(host * hst,char * varname,char * varvalue)927 customvariablesmember *add_custom_variable_to_host(host *hst, char *varname, char *varvalue) {
928
929 return add_custom_variable_to_object(&hst->custom_variables, varname, varvalue);
930 }
931
932
933
934 /* add a new host group to the list in memory */
add_hostgroup(char * name,char * alias,char * notes,char * notes_url,char * action_url)935 hostgroup *add_hostgroup(char *name, char *alias, char *notes, char *notes_url, char *action_url) {
936 hostgroup *new_hostgroup = NULL;
937 int result = OK;
938
939 /* make sure we have the data we need */
940 if(name == NULL || !strcmp(name, "")) {
941 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Hostgroup name is NULL\n");
942 return NULL;
943 }
944
945 new_hostgroup = calloc(1, sizeof(*new_hostgroup));
946
947 /* assign vars */
948 new_hostgroup->group_name = name;
949 new_hostgroup->alias = alias ? alias : name;
950 new_hostgroup->notes = notes;
951 new_hostgroup->notes_url = notes_url;
952 new_hostgroup->action_url = action_url;
953
954 /* add new host group to hash table */
955 if(result == OK) {
956 result = dkhash_insert(object_hash_tables[HOSTGROUP_SKIPLIST], new_hostgroup->group_name, NULL, new_hostgroup);
957 switch(result) {
958 case DKHASH_EDUPE:
959 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Hostgroup '%s' has already been defined\n", name);
960 result = ERROR;
961 break;
962 case DKHASH_OK:
963 result = OK;
964 break;
965 default:
966 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add hostgroup '%s' to hash table\n", name);
967 result = ERROR;
968 break;
969 }
970 }
971
972 /* handle errors */
973 if(result == ERROR) {
974 free(new_hostgroup);
975 return NULL;
976 }
977
978 new_hostgroup->id = num_objects.hostgroups++;
979 hostgroup_ary[new_hostgroup->id] = new_hostgroup;
980 if(new_hostgroup->id)
981 hostgroup_ary[new_hostgroup->id - 1]->next = new_hostgroup;
982 return new_hostgroup;
983 }
984
985
986 /* add a new host to a host group */
add_host_to_hostgroup(hostgroup * temp_hostgroup,char * host_name)987 hostsmember *add_host_to_hostgroup(hostgroup *temp_hostgroup, char *host_name) {
988 hostsmember *new_member = NULL;
989 hostsmember *last_member = NULL;
990 hostsmember *temp_member = NULL;
991 struct host *h;
992
993 /* make sure we have the data we need */
994 if(temp_hostgroup == NULL || (host_name == NULL || !strcmp(host_name, ""))) {
995 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Hostgroup or group member is NULL\n");
996 return NULL;
997 }
998 if (!(h = find_host(host_name))) {
999 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Failed to locate host '%s' for hostgroup '%s'\n", host_name, temp_hostgroup->group_name);
1000 return NULL;
1001 }
1002
1003 /* allocate memory for a new member */
1004 if((new_member = calloc(1, sizeof(hostsmember))) == NULL)
1005 return NULL;
1006
1007 /* assign vars */
1008 new_member->host_name = h->name;
1009 new_member->host_ptr = h;
1010
1011 /* add (unsorted) link from the host to its group */
1012 prepend_object_to_objectlist(&h->hostgroups_ptr, (void *)temp_hostgroup);
1013
1014 /* add the new member to the member list, sorted by host name */
1015 #ifndef NSCGI
1016 if(use_large_installation_tweaks == TRUE) {
1017 new_member->next = temp_hostgroup->members;
1018 temp_hostgroup->members = new_member;
1019 return new_member;
1020 }
1021 #endif
1022 last_member = temp_hostgroup->members;
1023 for(temp_member = temp_hostgroup->members; temp_member != NULL; temp_member = temp_member->next) {
1024 if(strcmp(new_member->host_name, temp_member->host_name) < 0) {
1025 new_member->next = temp_member;
1026 if(temp_member == temp_hostgroup->members)
1027 temp_hostgroup->members = new_member;
1028 else
1029 last_member->next = new_member;
1030 break;
1031 }
1032 else
1033 last_member = temp_member;
1034 }
1035 if(temp_hostgroup->members == NULL) {
1036 new_member->next = NULL;
1037 temp_hostgroup->members = new_member;
1038 }
1039 else if(temp_member == NULL) {
1040 new_member->next = NULL;
1041 last_member->next = new_member;
1042 }
1043
1044 return new_member;
1045 }
1046
1047
1048 /* add a new service group to the list in memory */
add_servicegroup(char * name,char * alias,char * notes,char * notes_url,char * action_url)1049 servicegroup *add_servicegroup(char *name, char *alias, char *notes, char *notes_url, char *action_url) {
1050 servicegroup *new_servicegroup = NULL;
1051 int result = OK;
1052
1053 /* make sure we have the data we need */
1054 if(name == NULL || !strcmp(name, "")) {
1055 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Servicegroup name is NULL\n");
1056 return NULL;
1057 }
1058
1059 new_servicegroup = calloc(1, sizeof(*new_servicegroup));
1060
1061 /* duplicate vars */
1062 new_servicegroup->group_name = name;
1063 new_servicegroup->alias = alias ? alias : name;
1064 new_servicegroup->notes = notes;
1065 new_servicegroup->notes_url = notes_url;
1066 new_servicegroup->action_url = action_url;
1067
1068 /* add new service group to hash table */
1069 if(result == OK) {
1070 result = dkhash_insert(object_hash_tables[SERVICEGROUP_SKIPLIST], new_servicegroup->group_name, NULL, new_servicegroup);
1071 switch(result) {
1072 case DKHASH_EDUPE:
1073 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Servicegroup '%s' has already been defined\n", name);
1074 result = ERROR;
1075 break;
1076 case DKHASH_OK:
1077 result = OK;
1078 break;
1079 default:
1080 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add servicegroup '%s' to hash table\n", name);
1081 result = ERROR;
1082 break;
1083 }
1084 }
1085
1086 /* handle errors */
1087 if(result == ERROR) {
1088 my_free(new_servicegroup);
1089 return NULL;
1090 }
1091
1092 new_servicegroup->id = num_objects.servicegroups++;
1093 servicegroup_ary[new_servicegroup->id] = new_servicegroup;
1094 if(new_servicegroup->id)
1095 servicegroup_ary[new_servicegroup->id - 1]->next = new_servicegroup;
1096 return new_servicegroup;
1097 }
1098
1099
1100 /* add a new service to a service group */
add_service_to_servicegroup(servicegroup * temp_servicegroup,char * host_name,char * svc_description)1101 servicesmember *add_service_to_servicegroup(servicegroup *temp_servicegroup, char *host_name, char *svc_description) {
1102 servicesmember *new_member = NULL;
1103 servicesmember *last_member = NULL;
1104 servicesmember *temp_member = NULL;
1105 struct service *svc;
1106
1107 /* make sure we have the data we need */
1108 if(temp_servicegroup == NULL || (host_name == NULL || !strcmp(host_name, "")) || (svc_description == NULL || !strcmp(svc_description, ""))) {
1109 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Servicegroup or group member is NULL\n");
1110 return NULL;
1111 }
1112 if (!(svc = find_service(host_name, svc_description))) {
1113 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Failed to locate service '%s' on host '%s' for servicegroup '%s'\n", svc_description, host_name, temp_servicegroup->group_name);
1114 return NULL;
1115 }
1116
1117 /* allocate memory for a new member */
1118 if((new_member = calloc(1, sizeof(servicesmember))) == NULL)
1119 return NULL;
1120
1121 /* assign vars */
1122 new_member->host_name = svc->host_name;
1123 new_member->service_description = svc->description;
1124 new_member->service_ptr = svc;
1125
1126 /* add (unsorted) link from the service to its groups */
1127 prepend_object_to_objectlist(&svc->servicegroups_ptr, temp_servicegroup);
1128
1129 /*
1130 * add new member to member list, sorted by host name then
1131 * service description, unless we're a large installation, in
1132 * which case insertion-sorting will take far too long
1133 */
1134 #ifndef NSCGI
1135 if(use_large_installation_tweaks == TRUE) {
1136 new_member->next = temp_servicegroup->members;
1137 temp_servicegroup->members = new_member;
1138 return new_member;
1139 }
1140 #endif
1141 last_member = temp_servicegroup->members;
1142 for(temp_member = temp_servicegroup->members; temp_member != NULL; temp_member = temp_member->next) {
1143
1144 if(strcmp(new_member->host_name, temp_member->host_name) < 0) {
1145 new_member->next = temp_member;
1146 if(temp_member == temp_servicegroup->members)
1147 temp_servicegroup->members = new_member;
1148 else
1149 last_member->next = new_member;
1150 break;
1151 }
1152
1153 else if(strcmp(new_member->host_name, temp_member->host_name) == 0 && strcmp(new_member->service_description, temp_member->service_description) < 0) {
1154 new_member->next = temp_member;
1155 if(temp_member == temp_servicegroup->members)
1156 temp_servicegroup->members = new_member;
1157 else
1158 last_member->next = new_member;
1159 break;
1160 }
1161
1162 else
1163 last_member = temp_member;
1164 }
1165 if(temp_servicegroup->members == NULL) {
1166 new_member->next = NULL;
1167 temp_servicegroup->members = new_member;
1168 }
1169 else if(temp_member == NULL) {
1170 new_member->next = NULL;
1171 last_member->next = new_member;
1172 }
1173
1174 return new_member;
1175 }
1176
1177
1178 /* add a new contact to the list in memory */
add_contact(char * name,char * alias,char * email,char * pager,char ** addresses,char * svc_notification_period,char * host_notification_period,int service_notification_options,int host_notification_options,int host_notifications_enabled,int service_notifications_enabled,int can_submit_commands,int retain_status_information,int retain_nonstatus_information,unsigned int minimum_value)1179 contact *add_contact(char *name, char *alias, char *email, char *pager, char **addresses, char *svc_notification_period, char *host_notification_period, int service_notification_options, int host_notification_options, int host_notifications_enabled, int service_notifications_enabled, int can_submit_commands, int retain_status_information, int retain_nonstatus_information, unsigned int minimum_value) {
1180 contact *new_contact = NULL;
1181 timeperiod *htp = NULL, *stp = NULL;
1182 int x = 0;
1183 int result = OK;
1184
1185 /* make sure we have the data we need */
1186 if(name == NULL || !*name) {
1187 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Contact name is NULL\n");
1188 return NULL;
1189 }
1190 if(svc_notification_period && !(stp = find_timeperiod(svc_notification_period))) {
1191 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Service notification period '%s' specified for contact '%s' is not defined anywhere!\n",
1192 svc_notification_period, name);
1193 return NULL;
1194 }
1195 if(host_notification_period && !(htp = find_timeperiod(host_notification_period))) {
1196 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Host notification period '%s' specified for contact '%s' is not defined anywhere!\n",
1197 host_notification_period, name);
1198 return NULL;
1199 }
1200
1201
1202 new_contact = calloc(1, sizeof(*new_contact));
1203 if(!new_contact)
1204 return NULL;
1205
1206
1207 new_contact->host_notification_period = htp ? (char *)strdup(htp->name) : NULL;
1208 new_contact->service_notification_period = stp ? (char *)strdup(stp->name) : NULL;
1209 new_contact->host_notification_period_ptr = htp;
1210 new_contact->service_notification_period_ptr = stp;
1211 new_contact->name = name;
1212 new_contact->alias = alias ? alias : name;
1213 new_contact->email = email;
1214 new_contact->pager = pager;
1215 if(addresses) {
1216 for(x = 0; x < MAX_CONTACT_ADDRESSES; x++)
1217 new_contact->address[x] = addresses[x];
1218 }
1219
1220 new_contact->minimum_value = minimum_value;
1221 new_contact->service_notification_options = service_notification_options;
1222 new_contact->host_notification_options = host_notification_options;
1223 new_contact->host_notifications_enabled = (host_notifications_enabled > 0) ? TRUE : FALSE;
1224 new_contact->service_notifications_enabled = (service_notifications_enabled > 0) ? TRUE : FALSE;
1225 new_contact->can_submit_commands = (can_submit_commands > 0) ? TRUE : FALSE;
1226 new_contact->retain_status_information = (retain_status_information > 0) ? TRUE : FALSE;
1227 new_contact->retain_nonstatus_information = (retain_nonstatus_information > 0) ? TRUE : FALSE;
1228
1229 /* add new contact to hash table */
1230 if(result == OK) {
1231 result = dkhash_insert(object_hash_tables[CONTACT_SKIPLIST], new_contact->name, NULL, new_contact);
1232 switch(result) {
1233 case DKHASH_EDUPE:
1234 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Contact '%s' has already been defined\n", name);
1235 result = ERROR;
1236 break;
1237 case DKHASH_OK:
1238 result = OK;
1239 break;
1240 default:
1241 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contact '%s' to hash table\n", name);
1242 result = ERROR;
1243 break;
1244 }
1245 }
1246
1247 /* handle errors */
1248 if(result == ERROR) {
1249 free(new_contact);
1250 return NULL;
1251 }
1252
1253 new_contact->id = num_objects.contacts++;
1254 contact_ary[new_contact->id] = new_contact;
1255 if(new_contact->id)
1256 contact_ary[new_contact->id - 1]->next = new_contact;
1257 return new_contact;
1258 }
1259
1260
1261
1262 /* adds a host notification command to a contact definition */
add_host_notification_command_to_contact(contact * cntct,char * command_name)1263 commandsmember *add_host_notification_command_to_contact(contact *cntct, char *command_name) {
1264 commandsmember *new_commandsmember = NULL;
1265 int result = OK;
1266
1267 /* make sure we have the data we need */
1268 if(cntct == NULL || (command_name == NULL || !strcmp(command_name, ""))) {
1269 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Contact or host notification command is NULL\n");
1270 return NULL;
1271 }
1272
1273 /* allocate memory */
1274 if((new_commandsmember = calloc(1, sizeof(commandsmember))) == NULL)
1275 return NULL;
1276
1277 /* duplicate vars */
1278 if((new_commandsmember->command = (char *)strdup(command_name)) == NULL)
1279 result = ERROR;
1280
1281 /* handle errors */
1282 if(result == ERROR) {
1283 my_free(new_commandsmember->command);
1284 my_free(new_commandsmember);
1285 return NULL;
1286 }
1287
1288 /* add the notification command */
1289 new_commandsmember->next = cntct->host_notification_commands;
1290 cntct->host_notification_commands = new_commandsmember;
1291
1292 return new_commandsmember;
1293 }
1294
1295
1296
1297 /* adds a service notification command to a contact definition */
add_service_notification_command_to_contact(contact * cntct,char * command_name)1298 commandsmember *add_service_notification_command_to_contact(contact *cntct, char *command_name) {
1299 commandsmember *new_commandsmember = NULL;
1300 int result = OK;
1301
1302 /* make sure we have the data we need */
1303 if(cntct == NULL || (command_name == NULL || !strcmp(command_name, ""))) {
1304 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Contact or service notification command is NULL\n");
1305 return NULL;
1306 }
1307
1308 /* allocate memory */
1309 if((new_commandsmember = calloc(1, sizeof(commandsmember))) == NULL)
1310 return NULL;
1311
1312 /* duplicate vars */
1313 if((new_commandsmember->command = (char *)strdup(command_name)) == NULL)
1314 result = ERROR;
1315
1316 /* handle errors */
1317 if(result == ERROR) {
1318 my_free(new_commandsmember->command);
1319 my_free(new_commandsmember);
1320 return NULL;
1321 }
1322
1323 /* add the notification command */
1324 new_commandsmember->next = cntct->service_notification_commands;
1325 cntct->service_notification_commands = new_commandsmember;
1326
1327 return new_commandsmember;
1328 }
1329
1330
1331
1332 /* adds a custom variable to a contact */
add_custom_variable_to_contact(contact * cntct,char * varname,char * varvalue)1333 customvariablesmember *add_custom_variable_to_contact(contact *cntct, char *varname, char *varvalue) {
1334
1335 return add_custom_variable_to_object(&cntct->custom_variables, varname, varvalue);
1336 }
1337
1338
1339
1340 /* add a new contact group to the list in memory */
add_contactgroup(char * name,char * alias)1341 contactgroup *add_contactgroup(char *name, char *alias) {
1342 contactgroup *new_contactgroup = NULL;
1343 int result = OK;
1344
1345 /* make sure we have the data we need */
1346 if(name == NULL || !strcmp(name, "")) {
1347 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Contactgroup name is NULL\n");
1348 return NULL;
1349 }
1350
1351 new_contactgroup = calloc(1, sizeof(*new_contactgroup));
1352 if(!new_contactgroup)
1353 return NULL;
1354
1355 /* assign vars */
1356 new_contactgroup->group_name = name;
1357 new_contactgroup->alias = alias ? alias : name;
1358
1359 /* add new contact group to hash table */
1360 if(result == OK) {
1361 result = dkhash_insert(object_hash_tables[CONTACTGROUP_SKIPLIST], new_contactgroup->group_name, NULL, new_contactgroup);
1362 switch(result) {
1363 case DKHASH_EDUPE:
1364 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Contactgroup '%s' has already been defined\n", name);
1365 result = ERROR;
1366 break;
1367 case DKHASH_OK:
1368 result = OK;
1369 break;
1370 default:
1371 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add contactgroup '%s' to hash table\n", name);
1372 result = ERROR;
1373 break;
1374 }
1375 }
1376
1377 /* handle errors */
1378 if(result == ERROR) {
1379 free(new_contactgroup);
1380 return NULL;
1381 }
1382
1383 new_contactgroup->id = num_objects.contactgroups++;
1384 contactgroup_ary[new_contactgroup->id] = new_contactgroup;
1385 if(new_contactgroup->id)
1386 contactgroup_ary[new_contactgroup->id - 1]->next = new_contactgroup;
1387 return new_contactgroup;
1388 }
1389
1390
1391
1392 /* add a new member to a contact group */
add_contact_to_contactgroup(contactgroup * grp,char * contact_name)1393 contactsmember *add_contact_to_contactgroup(contactgroup *grp, char *contact_name) {
1394 contactsmember *new_contactsmember = NULL;
1395 struct contact *c;
1396
1397 /* make sure we have the data we need */
1398 if(grp == NULL || (contact_name == NULL || !strcmp(contact_name, ""))) {
1399 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Contactgroup or contact name is NULL\n");
1400 return NULL;
1401 }
1402
1403 if (!(c = find_contact(contact_name))) {
1404 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Failed to locate contact '%s' for contactgroup '%s'\n", contact_name, grp->group_name);
1405 return NULL;
1406 }
1407
1408 /* allocate memory for a new member */
1409 if((new_contactsmember = calloc(1, sizeof(contactsmember))) == NULL)
1410 return NULL;
1411
1412 /* assign vars */
1413 new_contactsmember->contact_name = c->name;
1414 new_contactsmember->contact_ptr = c;
1415
1416 /* add the new member to the head of the member list */
1417 new_contactsmember->next = grp->members;
1418 grp->members = new_contactsmember;
1419
1420 prepend_object_to_objectlist(&c->contactgroups_ptr, (void *)grp);
1421
1422 return new_contactsmember;
1423 }
1424
1425
1426
1427 /* add a new service to the list in memory */
add_service(char * host_name,char * description,char * display_name,char * check_period,int initial_state,int max_attempts,int parallelize,int accept_passive_checks,double check_interval,double retry_interval,double notification_interval,double first_notification_delay,char * notification_period,int notification_options,int notifications_enabled,int is_volatile,char * event_handler,int event_handler_enabled,char * check_command,int checks_enabled,int flap_detection_enabled,double low_flap_threshold,double high_flap_threshold,int flap_detection_options,int stalking_options,int process_perfdata,int check_freshness,int freshness_threshold,char * notes,char * notes_url,char * action_url,char * icon_image,char * icon_image_alt,int retain_status_information,int retain_nonstatus_information,int obsess,unsigned int hourly_value)1428 service *add_service(char *host_name, char *description, char *display_name, char *check_period, int initial_state, int max_attempts, int parallelize, int accept_passive_checks, double check_interval, double retry_interval, double notification_interval, double first_notification_delay, char *notification_period, int notification_options, int notifications_enabled, int is_volatile, char *event_handler, int event_handler_enabled, char *check_command, int checks_enabled, int flap_detection_enabled, double low_flap_threshold, double high_flap_threshold, int flap_detection_options, int stalking_options, int process_perfdata, int check_freshness, int freshness_threshold, char *notes, char *notes_url, char *action_url, char *icon_image, char *icon_image_alt, int retain_status_information, int retain_nonstatus_information, int obsess, unsigned int hourly_value) {
1429 host *h;
1430 timeperiod *cp = NULL, *np = NULL;
1431 service *new_service = NULL;
1432 int result = OK;
1433
1434 /* make sure we have everything we need */
1435 if(host_name == NULL || description == NULL || !*description || check_command == NULL || !*check_command) {
1436 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Service description, host name, or check command is NULL\n");
1437 return NULL;
1438 }
1439 if (!(h = find_host(host_name))) {
1440 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Unable to locate host '%s' for service '%s'\n",
1441 host_name, description);
1442 return NULL;
1443 }
1444 if(notification_period && !(np = find_timeperiod(notification_period))) {
1445 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: notification_period '%s' for service '%s' on host '%s' could not be found!\n",
1446 notification_period, description, host_name);
1447 return NULL;
1448 }
1449 if(check_period && !(cp = find_timeperiod(check_period))) {
1450 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: check_period '%s' for service '%s' on host '%s' not found!\n",
1451 check_period, description, host_name);
1452 return NULL;
1453 }
1454
1455 /* check values */
1456 if(max_attempts <= 0 || check_interval < 0 || retry_interval <= 0 || notification_interval < 0) {
1457 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid max_attempts, check_interval, retry_interval, or notification_interval value for service '%s' on host '%s'\n", description, host_name);
1458 return NULL;
1459 }
1460
1461 if(first_notification_delay < 0) {
1462 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Invalid first_notification_delay value for service '%s' on host '%s'\n", description, host_name);
1463 return NULL;
1464 }
1465
1466 /* allocate memory */
1467 new_service = calloc(1, sizeof(*new_service));
1468 if(!new_service)
1469 return NULL;
1470
1471 /* duplicate vars, but assign what we can */
1472 new_service->notification_period_ptr = np;
1473 new_service->check_period_ptr = cp;
1474 new_service->host_ptr = h;
1475 new_service->check_period = cp ? (char *)strdup(cp->name) : NULL;
1476 new_service->notification_period = np ? (char *)strdup(np->name) : NULL;
1477 new_service->host_name = h->name;
1478 if((new_service->description = (char *)strdup(description)) == NULL)
1479 result = ERROR;
1480 if(display_name) {
1481 if((new_service->display_name = (char *)strdup(display_name)) == NULL)
1482 result = ERROR;
1483 }
1484 else {
1485 new_service->display_name = new_service->description;
1486 }
1487 if((new_service->check_command = (char *)strdup(check_command)) == NULL)
1488 result = ERROR;
1489 if(event_handler) {
1490 if((new_service->event_handler = (char *)strdup(event_handler)) == NULL)
1491 result = ERROR;
1492 }
1493 if(notes) {
1494 if((new_service->notes = (char *)strdup(notes)) == NULL)
1495 result = ERROR;
1496 }
1497 if(notes_url) {
1498 if((new_service->notes_url = (char *)strdup(notes_url)) == NULL)
1499 result = ERROR;
1500 }
1501 if(action_url) {
1502 if((new_service->action_url = (char *)strdup(action_url)) == NULL)
1503 result = ERROR;
1504 }
1505 if(icon_image) {
1506 if((new_service->icon_image = (char *)strdup(icon_image)) == NULL)
1507 result = ERROR;
1508 }
1509 if(icon_image_alt) {
1510 if((new_service->icon_image_alt = (char *)strdup(icon_image_alt)) == NULL)
1511 result = ERROR;
1512 }
1513
1514 new_service->hourly_value = hourly_value;
1515 new_service->check_interval = check_interval;
1516 new_service->retry_interval = retry_interval;
1517 new_service->max_attempts = max_attempts;
1518 new_service->parallelize = (parallelize > 0) ? TRUE : FALSE;
1519 new_service->notification_interval = notification_interval;
1520 new_service->first_notification_delay = first_notification_delay;
1521 new_service->notification_options = notification_options;
1522 new_service->is_volatile = (is_volatile > 0) ? TRUE : FALSE;
1523 new_service->flap_detection_enabled = (flap_detection_enabled > 0) ? TRUE : FALSE;
1524 new_service->low_flap_threshold = low_flap_threshold;
1525 new_service->high_flap_threshold = high_flap_threshold;
1526 new_service->flap_detection_options = flap_detection_options;
1527 new_service->stalking_options = stalking_options;
1528 new_service->process_performance_data = (process_perfdata > 0) ? TRUE : FALSE;
1529 new_service->check_freshness = (check_freshness > 0) ? TRUE : FALSE;
1530 new_service->freshness_threshold = freshness_threshold;
1531 new_service->accept_passive_checks = (accept_passive_checks > 0) ? TRUE : FALSE;
1532 new_service->event_handler_enabled = (event_handler_enabled > 0) ? TRUE : FALSE;
1533 new_service->checks_enabled = (checks_enabled > 0) ? TRUE : FALSE;
1534 new_service->retain_status_information = (retain_status_information > 0) ? TRUE : FALSE;
1535 new_service->retain_nonstatus_information = (retain_nonstatus_information > 0) ? TRUE : FALSE;
1536 new_service->notifications_enabled = (notifications_enabled > 0) ? TRUE : FALSE;
1537 new_service->obsess = (obsess > 0) ? TRUE : FALSE;
1538 #ifdef NSCORE
1539 new_service->acknowledgement_type = ACKNOWLEDGEMENT_NONE;
1540 new_service->check_type = CHECK_TYPE_ACTIVE;
1541 new_service->current_attempt = (initial_state == STATE_OK) ? 1 : max_attempts;
1542 new_service->current_state = initial_state;
1543 new_service->last_state = initial_state;
1544 new_service->last_hard_state = initial_state;
1545 new_service->state_type = HARD_STATE;
1546 new_service->should_be_scheduled = TRUE;
1547 new_service->check_options = CHECK_OPTION_NONE;
1548 #endif
1549
1550 /* add new service to hash table */
1551 if(result == OK) {
1552 result = dkhash_insert(object_hash_tables[SERVICE_SKIPLIST], new_service->host_name, new_service->description, new_service);
1553 switch(result) {
1554 case DKHASH_EDUPE:
1555 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Service '%s' on host '%s' has already been defined\n", description, host_name);
1556 result = ERROR;
1557 break;
1558 case DKHASH_OK:
1559 result = OK;
1560 break;
1561 default:
1562 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add service '%s' on host '%s' to hash table\n", description, host_name);
1563 result = ERROR;
1564 break;
1565 }
1566 }
1567
1568 /* handle errors */
1569 if(result == ERROR) {
1570 #ifdef NSCORE
1571 my_free(new_service->perf_data);
1572 my_free(new_service->plugin_output);
1573 my_free(new_service->long_plugin_output);
1574 #endif
1575 my_free(new_service->event_handler);
1576 my_free(new_service->check_command);
1577 my_free(new_service->description);
1578 if(display_name)
1579 my_free(new_service->display_name);
1580 return NULL;
1581 }
1582
1583 add_service_link_to_host(h, new_service);
1584
1585 new_service->id = num_objects.services++;
1586 service_ary[new_service->id] = new_service;
1587 if(new_service->id)
1588 service_ary[new_service->id - 1]->next = new_service;
1589 return new_service;
1590 }
1591
1592
1593
1594 /* adds a contact group to a service */
add_contactgroup_to_service(service * svc,char * group_name)1595 contactgroupsmember *add_contactgroup_to_service(service *svc, char *group_name) {
1596 return add_contactgroup_to_object(&svc->contact_groups, group_name);
1597 }
1598
1599
1600
1601 /* adds a contact to a service */
add_contact_to_service(service * svc,char * contact_name)1602 contactsmember *add_contact_to_service(service *svc, char *contact_name) {
1603
1604 return add_contact_to_object(&svc->contacts, contact_name);
1605 }
1606
1607
1608
1609 /* adds a custom variable to a service */
add_custom_variable_to_service(service * svc,char * varname,char * varvalue)1610 customvariablesmember *add_custom_variable_to_service(service *svc, char *varname, char *varvalue) {
1611
1612 return add_custom_variable_to_object(&svc->custom_variables, varname, varvalue);
1613 }
1614
1615
1616
1617 /* add a new command to the list in memory */
add_command(char * name,char * value)1618 command *add_command(char *name, char *value) {
1619 command *new_command = NULL;
1620 int result = OK;
1621
1622 /* make sure we have the data we need */
1623 if((name == NULL || !strcmp(name, "")) || (value == NULL || !strcmp(value, ""))) {
1624 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Command name of command line is NULL\n");
1625 return NULL;
1626 }
1627
1628 /* allocate memory for the new command */
1629 new_command = calloc(1, sizeof(*new_command));
1630 if(!new_command)
1631 return NULL;
1632
1633 /* assign vars */
1634 new_command->name = name;
1635 new_command->command_line = value;
1636
1637 /* add new command to hash table */
1638 if(result == OK) {
1639 result = dkhash_insert(object_hash_tables[COMMAND_SKIPLIST], new_command->name, NULL, new_command);
1640 switch(result) {
1641 case DKHASH_EDUPE:
1642 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Command '%s' has already been defined\n", name);
1643 result = ERROR;
1644 break;
1645 case DKHASH_OK:
1646 result = OK;
1647 break;
1648 default:
1649 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add command '%s' to hash table\n", name);
1650 result = ERROR;
1651 break;
1652 }
1653 }
1654
1655 /* handle errors */
1656 if(result == ERROR) {
1657 my_free(new_command);
1658 return NULL;
1659 }
1660
1661 new_command->id = num_objects.commands++;
1662 command_ary[new_command->id] = new_command;
1663 if(new_command->id)
1664 command_ary[new_command->id - 1]->next = new_command;
1665 return new_command;
1666 }
1667
1668
1669
1670 /* add a new service escalation to the list in memory */
add_serviceescalation(char * host_name,char * description,int first_notification,int last_notification,double notification_interval,char * escalation_period,int escalation_options)1671 serviceescalation *add_serviceescalation(char *host_name, char *description, int first_notification, int last_notification, double notification_interval, char *escalation_period, int escalation_options) {
1672 serviceescalation *new_serviceescalation = NULL;
1673 service *svc;
1674 timeperiod *tp = NULL;
1675
1676 /* make sure we have the data we need */
1677 if(host_name == NULL || !*host_name || description == NULL || !*description) {
1678 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Service escalation host name or description is NULL\n");
1679 return NULL;
1680 }
1681 if(!(svc = find_service(host_name, description))) {
1682 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Service '%s' on host '%s' has an escalation but is not defined anywhere!\n",
1683 host_name, description);
1684 return NULL;
1685 }
1686 if (escalation_period && !(tp = find_timeperiod(escalation_period))) {
1687 logit(NSLOG_VERIFICATION_ERROR, TRUE, "Error: Escalation period '%s' specified in service escalation for service '%s' on host '%s' is not defined anywhere!\n",
1688 escalation_period, description, host_name);
1689 return NULL ;
1690 }
1691
1692 new_serviceescalation = calloc(1, sizeof(*new_serviceescalation));
1693 if(!new_serviceescalation)
1694 return NULL;
1695
1696 if(add_object_to_objectlist(&svc->escalation_list, new_serviceescalation) != OK) {
1697 logit(NSLOG_CONFIG_ERROR, TRUE, "Could not add escalation to service '%s' on host '%s'\n",
1698 svc->host_name, svc->description);
1699 return NULL;
1700 }
1701
1702 /* assign vars. object names are immutable, so no need to copy */
1703 new_serviceescalation->host_name = svc->host_name;
1704 new_serviceescalation->description = svc->description;
1705 new_serviceescalation->service_ptr = svc;
1706 new_serviceescalation->escalation_period_ptr = tp;
1707 if(tp)
1708 new_serviceescalation->escalation_period = (char *)strdup(tp->name);
1709
1710 new_serviceescalation->first_notification = first_notification;
1711 new_serviceescalation->last_notification = last_notification;
1712 new_serviceescalation->notification_interval = (notification_interval <= 0) ? 0 : notification_interval;
1713 new_serviceescalation->escalation_options = escalation_options;
1714
1715 new_serviceescalation->id = num_objects.serviceescalations++;
1716 serviceescalation_ary[new_serviceescalation->id] = new_serviceescalation;
1717 return new_serviceescalation;
1718 }
1719
1720
1721
1722 /* adds a contact group to a service escalation */
add_contactgroup_to_serviceescalation(serviceescalation * se,char * group_name)1723 contactgroupsmember *add_contactgroup_to_serviceescalation(serviceescalation *se, char *group_name) {
1724 return add_contactgroup_to_object(&se->contact_groups, group_name);
1725 }
1726
1727
1728
1729 /* adds a contact to a service escalation */
add_contact_to_serviceescalation(serviceescalation * se,char * contact_name)1730 contactsmember *add_contact_to_serviceescalation(serviceescalation *se, char *contact_name) {
1731
1732 return add_contact_to_object(&se->contacts, contact_name);
1733 }
1734
1735
1736
1737 /* adds a service dependency definition */
add_service_dependency(char * dependent_host_name,char * dependent_service_description,char * host_name,char * service_description,int dependency_type,int inherits_parent,int failure_options,char * dependency_period)1738 servicedependency *add_service_dependency(char *dependent_host_name, char *dependent_service_description, char *host_name, char *service_description, int dependency_type, int inherits_parent, int failure_options, char *dependency_period) {
1739 servicedependency *new_servicedependency = NULL;
1740 service *parent, *child;
1741 timeperiod *tp = NULL;
1742 int result;
1743
1744 /* make sure we have what we need */
1745 parent = find_service(host_name, service_description);
1746 if(!parent) {
1747 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Master service '%s' on host '%s' is not defined anywhere!\n",
1748 service_description, host_name);
1749 return NULL;
1750 }
1751 child = find_service(dependent_host_name, dependent_service_description);
1752 if(!child) {
1753 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Dependent service '%s' on host '%s' is not defined anywhere!\n",
1754 dependent_service_description, dependent_host_name);
1755 return NULL;
1756 }
1757 if (dependency_period && !(tp = find_timeperiod(dependency_period))) {
1758 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Failed to locate timeperiod '%s' for dependency from service '%s' on host '%s' to service '%s' on host '%s'\n",
1759 dependency_period, dependent_service_description, dependent_host_name, service_description, host_name);
1760 return NULL;
1761 }
1762
1763 /* allocate memory for a new service dependency entry */
1764 if((new_servicedependency = calloc(1, sizeof(*new_servicedependency))) == NULL)
1765 return NULL;
1766
1767 new_servicedependency->dependent_service_ptr = child;
1768 new_servicedependency->master_service_ptr = parent;
1769 new_servicedependency->dependency_period_ptr = tp;
1770
1771 /* assign vars. object names are immutable, so no need to copy */
1772 new_servicedependency->dependent_host_name = child->host_name;
1773 new_servicedependency->dependent_service_description = child->description;
1774 new_servicedependency->host_name = parent->host_name;
1775 new_servicedependency->service_description = parent->description;
1776 if (tp)
1777 new_servicedependency->dependency_period = (char *)strdup(tp->name);
1778
1779 new_servicedependency->dependency_type = (dependency_type == EXECUTION_DEPENDENCY) ? EXECUTION_DEPENDENCY : NOTIFICATION_DEPENDENCY;
1780 new_servicedependency->inherits_parent = (inherits_parent > 0) ? TRUE : FALSE;
1781 new_servicedependency->failure_options = failure_options;
1782
1783 /*
1784 * add new service dependency to its respective services.
1785 * Ordering doesn't matter here as we'll have to check them
1786 * all anyway. We avoid adding dupes though, since we can
1787 * apparently get zillion's and zillion's of them.
1788 */
1789 if(dependency_type == NOTIFICATION_DEPENDENCY)
1790 result = prepend_unique_object_to_objectlist(&child->notify_deps, new_servicedependency, sizeof(*new_servicedependency));
1791 else
1792 result = prepend_unique_object_to_objectlist(&child->exec_deps, new_servicedependency, sizeof(*new_servicedependency));
1793
1794 if(result != OK) {
1795 free(new_servicedependency);
1796 /* hack to avoid caller bombing out */
1797 return result == OBJECTLIST_DUPE ? (void *)1 : NULL;
1798 }
1799
1800 num_objects.servicedependencies++;
1801 return new_servicedependency;
1802 }
1803
1804
1805 /* adds a host dependency definition */
add_host_dependency(char * dependent_host_name,char * host_name,int dependency_type,int inherits_parent,int failure_options,char * dependency_period)1806 hostdependency *add_host_dependency(char *dependent_host_name, char *host_name, int dependency_type, int inherits_parent, int failure_options, char *dependency_period) {
1807 hostdependency *new_hostdependency = NULL;
1808 host *parent, *child;
1809 timeperiod *tp = NULL;
1810 int result;
1811
1812 /* make sure we have what we need */
1813 parent = find_host(host_name);
1814 if (!parent) {
1815 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Master host '%s' in hostdependency from '%s' to '%s' is not defined anywhere!\n",
1816 host_name, dependent_host_name, host_name);
1817 return NULL;
1818 }
1819 child = find_host(dependent_host_name);
1820 if (!child) {
1821 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Dependent host '%s' in hostdependency from '%s' to '%s' is not defined anywhere!\n",
1822 dependent_host_name, dependent_host_name, host_name);
1823 return NULL;
1824 }
1825 if (dependency_period && !(tp = find_timeperiod(dependency_period))) {
1826 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Unable to locate dependency_period '%s' for %s->%s host dependency\n",
1827 dependency_period, parent->name, child->name);
1828 return NULL ;
1829 }
1830
1831 if((new_hostdependency = calloc(1, sizeof(*new_hostdependency))) == NULL)
1832 return NULL;
1833
1834 new_hostdependency->dependent_host_ptr = child;
1835 new_hostdependency->master_host_ptr = parent;
1836 new_hostdependency->dependency_period_ptr = tp;
1837
1838 /* assign vars. Objects are immutable, so no need to copy */
1839 new_hostdependency->dependent_host_name = child->name;
1840 new_hostdependency->host_name = parent->name;
1841 if(tp)
1842 new_hostdependency->dependency_period = (char *)strdup(tp->name);
1843
1844 new_hostdependency->dependency_type = (dependency_type == EXECUTION_DEPENDENCY) ? EXECUTION_DEPENDENCY : NOTIFICATION_DEPENDENCY;
1845 new_hostdependency->inherits_parent = (inherits_parent > 0) ? TRUE : FALSE;
1846 new_hostdependency->failure_options = failure_options;
1847
1848 if(dependency_type == NOTIFICATION_DEPENDENCY)
1849 result = prepend_unique_object_to_objectlist(&child->notify_deps, new_hostdependency, sizeof(*new_hostdependency));
1850 else
1851 result = prepend_unique_object_to_objectlist(&child->exec_deps, new_hostdependency, sizeof(*new_hostdependency));
1852
1853 if(result != OK) {
1854 free(new_hostdependency);
1855 /* hack to avoid caller bombing out */
1856 return result == OBJECTLIST_DUPE ? (void *)1 : NULL;
1857 }
1858
1859 num_objects.hostdependencies++;
1860 return new_hostdependency;
1861 }
1862
1863
1864
1865 /* add a new host escalation to the list in memory */
add_hostescalation(char * host_name,int first_notification,int last_notification,double notification_interval,char * escalation_period,int escalation_options)1866 hostescalation *add_hostescalation(char *host_name, int first_notification, int last_notification, double notification_interval, char *escalation_period, int escalation_options) {
1867 hostescalation *new_hostescalation = NULL;
1868 host *h;
1869 timeperiod *tp = NULL;
1870
1871 /* make sure we have the data we need */
1872 if(host_name == NULL || !*host_name) {
1873 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Host escalation host name is NULL\n");
1874 return NULL;
1875 }
1876 if (!(h = find_host(host_name))) {
1877 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Host '%s' has an escalation, but is not defined anywhere!\n", host_name);
1878 return NULL;
1879 }
1880 if (escalation_period && !(tp = find_timeperiod(escalation_period))) {
1881 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Unable to locate timeperiod '%s' for hostescalation '%s'\n",
1882 escalation_period, host_name);
1883 return NULL;
1884 }
1885
1886 new_hostescalation = calloc(1, sizeof(*new_hostescalation));
1887
1888 /* add the escalation to its host */
1889 if (add_object_to_objectlist(&h->escalation_list, new_hostescalation) != OK) {
1890 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not add hostescalation to host '%s'\n", host_name);
1891 free(new_hostescalation);
1892 return NULL;
1893 }
1894
1895 /* assign vars. Object names are immutable, so no need to copy */
1896 new_hostescalation->host_name = h->name;
1897 new_hostescalation->host_ptr = h;
1898 new_hostescalation->escalation_period = tp ? (char *)strdup(tp->name) : NULL;
1899 new_hostescalation->escalation_period_ptr = tp;
1900 new_hostescalation->first_notification = first_notification;
1901 new_hostescalation->last_notification = last_notification;
1902 new_hostescalation->notification_interval = (notification_interval <= 0) ? 0 : notification_interval;
1903 new_hostescalation->escalation_options = escalation_options;
1904
1905 new_hostescalation->id = num_objects.hostescalations++;
1906 hostescalation_ary[new_hostescalation->id] = new_hostescalation;
1907 return new_hostescalation;
1908 }
1909
1910
1911
1912 /* adds a contact group to a host escalation */
add_contactgroup_to_hostescalation(hostescalation * he,char * group_name)1913 contactgroupsmember *add_contactgroup_to_hostescalation(hostescalation *he, char *group_name) {
1914 return add_contactgroup_to_object(&he->contact_groups, group_name);
1915 }
1916
1917
1918
1919 /* adds a contact to a host escalation */
add_contact_to_hostescalation(hostescalation * he,char * contact_name)1920 contactsmember *add_contact_to_hostescalation(hostescalation *he, char *contact_name) {
1921
1922 return add_contact_to_object(&he->contacts, contact_name);
1923 }
1924
1925
1926
1927 /* adds a contact to an object */
add_contact_to_object(contactsmember ** object_ptr,char * contactname)1928 contactsmember *add_contact_to_object(contactsmember **object_ptr, char *contactname) {
1929 contactsmember *new_contactsmember = NULL;
1930 contact *c;
1931
1932 /* make sure we have the data we need */
1933 if(object_ptr == NULL) {
1934 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Contact object is NULL\n");
1935 return NULL;
1936 }
1937
1938 if(contactname == NULL || !*contactname) {
1939 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Contact name is NULL\n");
1940 return NULL;
1941 }
1942 if(!(c = find_contact(contactname))) {
1943 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Contact '%s' is not defined anywhere!\n", contactname);
1944 return NULL;
1945 }
1946
1947 /* allocate memory for a new member */
1948 if((new_contactsmember = malloc(sizeof(contactsmember))) == NULL) {
1949 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not allocate memory for contact\n");
1950 return NULL;
1951 }
1952 new_contactsmember->contact_name = c->name;
1953
1954 /* set initial values */
1955 new_contactsmember->contact_ptr = c;
1956
1957 /* add the new contact to the head of the contact list */
1958 new_contactsmember->next = *object_ptr;
1959 *object_ptr = new_contactsmember;
1960
1961 return new_contactsmember;
1962 }
1963
1964
1965
1966 /* adds a custom variable to an object */
add_custom_variable_to_object(customvariablesmember ** object_ptr,char * varname,char * varvalue)1967 customvariablesmember *add_custom_variable_to_object(customvariablesmember **object_ptr, char *varname, char *varvalue) {
1968 customvariablesmember *new_customvariablesmember = NULL;
1969
1970 /* make sure we have the data we need */
1971 if(object_ptr == NULL) {
1972 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Custom variable object is NULL\n");
1973 return NULL;
1974 }
1975
1976 if(varname == NULL || !strcmp(varname, "")) {
1977 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Custom variable name is NULL\n");
1978 return NULL;
1979 }
1980
1981 /* allocate memory for a new member */
1982 if((new_customvariablesmember = malloc(sizeof(customvariablesmember))) == NULL) {
1983 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not allocate memory for custom variable\n");
1984 return NULL;
1985 }
1986 if((new_customvariablesmember->variable_name = (char *)strdup(varname)) == NULL) {
1987 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not allocate memory for custom variable name\n");
1988 my_free(new_customvariablesmember);
1989 return NULL;
1990 }
1991 if(varvalue) {
1992 if((new_customvariablesmember->variable_value = (char *)strdup(varvalue)) == NULL) {
1993 logit(NSLOG_CONFIG_ERROR, TRUE, "Error: Could not allocate memory for custom variable value\n");
1994 my_free(new_customvariablesmember->variable_name);
1995 my_free(new_customvariablesmember);
1996 return NULL;
1997 }
1998 }
1999 else
2000 new_customvariablesmember->variable_value = NULL;
2001
2002 /* set initial values */
2003 new_customvariablesmember->has_been_modified = FALSE;
2004
2005 /* add the new member to the head of the member list */
2006 new_customvariablesmember->next = *object_ptr;
2007 *object_ptr = new_customvariablesmember;
2008
2009 return new_customvariablesmember;
2010 }
2011
2012
2013
2014
2015 /******************************************************************/
2016 /******************** OBJECT SEARCH FUNCTIONS *********************/
2017 /******************************************************************/
2018
find_timeperiod(const char * name)2019 timeperiod *find_timeperiod(const char *name) {
2020 return dkhash_get(object_hash_tables[TIMEPERIOD_SKIPLIST], name, NULL);
2021 }
2022
find_host(const char * name)2023 host *find_host(const char *name) {
2024 return dkhash_get(object_hash_tables[HOST_SKIPLIST], name, NULL);
2025 }
2026
find_hostgroup(const char * name)2027 hostgroup *find_hostgroup(const char *name) {
2028 return dkhash_get(object_hash_tables[HOSTGROUP_SKIPLIST], name, NULL);
2029 }
2030
find_servicegroup(const char * name)2031 servicegroup *find_servicegroup(const char *name) {
2032 return dkhash_get(object_hash_tables[SERVICEGROUP_SKIPLIST], name, NULL);
2033 }
2034
find_contact(const char * name)2035 contact *find_contact(const char *name) {
2036 return dkhash_get(object_hash_tables[CONTACT_SKIPLIST], name, NULL);
2037 }
2038
find_contactgroup(const char * name)2039 contactgroup *find_contactgroup(const char *name) {
2040 return dkhash_get(object_hash_tables[CONTACTGROUP_SKIPLIST], name, NULL);
2041 }
2042
find_command(const char * name)2043 command *find_command(const char *name) {
2044 return dkhash_get(object_hash_tables[COMMAND_SKIPLIST], name, NULL);
2045 }
2046
find_service(const char * host_name,const char * svc_desc)2047 service *find_service(const char *host_name, const char *svc_desc) {
2048 return dkhash_get(object_hash_tables[SERVICE_SKIPLIST], host_name, svc_desc);
2049 }
2050
2051
2052
2053 /* adds a object to a list of objects */
add_object_to_objectlist(objectlist ** list,void * object_ptr)2054 int add_object_to_objectlist(objectlist **list, void *object_ptr) {
2055 objectlist *temp_item = NULL;
2056 objectlist *new_item = NULL;
2057
2058 if(list == NULL || object_ptr == NULL)
2059 return ERROR;
2060
2061 /* skip this object if its already in the list */
2062 for(temp_item = *list; temp_item; temp_item = temp_item->next) {
2063 if(temp_item->object_ptr == object_ptr)
2064 break;
2065 }
2066 if(temp_item)
2067 return OK;
2068
2069 /* allocate memory for a new list item */
2070 if((new_item = (objectlist *)malloc(sizeof(objectlist))) == NULL)
2071 return ERROR;
2072
2073 /* initialize vars */
2074 new_item->object_ptr = object_ptr;
2075
2076 /* add new item to head of list */
2077 new_item->next = *list;
2078 *list = new_item;
2079
2080 return OK;
2081 }
2082
2083
2084 /* useful when we don't care if the object is unique or not */
prepend_object_to_objectlist(objectlist ** list,void * object_ptr)2085 int prepend_object_to_objectlist(objectlist **list, void *object_ptr)
2086 {
2087 objectlist *item;
2088 if(list == NULL || object_ptr == NULL)
2089 return ERROR;
2090 if((item = malloc(sizeof(*item))) == NULL)
2091 return ERROR;
2092 item->next = *list;
2093 item->object_ptr = object_ptr;
2094 *list = item;
2095 return OK;
2096 }
2097
2098 /* useful for adding dependencies to master objects */
prepend_unique_object_to_objectlist(objectlist ** list,void * object_ptr,size_t size)2099 int prepend_unique_object_to_objectlist(objectlist **list, void *object_ptr, size_t size) {
2100 objectlist *l;
2101 if(list == NULL || object_ptr == NULL)
2102 return ERROR;
2103 for(l = *list; l; l = l->next) {
2104 if(!memcmp(l->object_ptr, object_ptr, size))
2105 return OBJECTLIST_DUPE;
2106 }
2107 return prepend_object_to_objectlist(list, object_ptr);
2108 }
2109
2110 /* frees memory allocated to a temporary object list */
free_objectlist(objectlist ** temp_list)2111 int free_objectlist(objectlist **temp_list) {
2112 objectlist *this_objectlist = NULL;
2113 objectlist *next_objectlist = NULL;
2114
2115 if(temp_list == NULL)
2116 return ERROR;
2117
2118 /* free memory allocated to object list */
2119 for(this_objectlist = *temp_list; this_objectlist != NULL; this_objectlist = next_objectlist) {
2120 next_objectlist = this_objectlist->next;
2121 my_free(this_objectlist);
2122 }
2123
2124 *temp_list = NULL;
2125
2126 return OK;
2127 }
2128
2129
2130
2131 /******************************************************************/
2132 /********************* OBJECT QUERY FUNCTIONS *********************/
2133 /******************************************************************/
2134
2135 /* determines whether or not a specific host is an immediate child of another host */
is_host_immediate_child_of_host(host * parent_host,host * child_host)2136 int is_host_immediate_child_of_host(host *parent_host, host *child_host) {
2137 hostsmember *temp_hostsmember = NULL;
2138
2139 /* not enough data */
2140 if(child_host == NULL)
2141 return FALSE;
2142
2143 /* root/top-level hosts */
2144 if(parent_host == NULL) {
2145 if(child_host->parent_hosts == NULL)
2146 return TRUE;
2147 }
2148
2149 /* mid-level/bottom hosts */
2150 else {
2151
2152 for(temp_hostsmember = child_host->parent_hosts; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) {
2153 if(temp_hostsmember->host_ptr == parent_host)
2154 return TRUE;
2155 }
2156 }
2157
2158 return FALSE;
2159 }
2160
2161
2162 /* determines whether or not a specific host is an immediate parent of another host */
is_host_immediate_parent_of_host(host * child_host,host * parent_host)2163 int is_host_immediate_parent_of_host(host *child_host, host *parent_host) {
2164
2165 if(is_host_immediate_child_of_host(parent_host, child_host) == TRUE)
2166 return TRUE;
2167
2168 return FALSE;
2169 }
2170
2171 #ifdef NSCGI
hostsmember_elements(hostsmember * list)2172 int hostsmember_elements(hostsmember *list)
2173 {
2174 int elems = 0;
2175 for (; list; list = list->next)
2176 elems++;
2177 return elems;
2178 }
2179
2180 /* returns a count of the immediate children for a given host */
2181 /* NOTE: This function is only used by the CGIS */
number_of_immediate_child_hosts(host * hst)2182 int number_of_immediate_child_hosts(host *hst) {
2183 int children = 0;
2184 host *temp_host = NULL;
2185
2186 if(hst == NULL) {
2187 for(temp_host = host_list; temp_host != NULL;
2188 temp_host = temp_host->next) {
2189 if(is_host_immediate_child_of_host(hst, temp_host) == TRUE)
2190 children++;
2191 }
2192 return children;
2193 }
2194 else {
2195 return hostsmember_elements(hst->child_hosts);
2196 }
2197 }
2198
2199
2200 /* get the number of immediate parent hosts for a given host */
2201 /* NOTE: This function is only used by the CGIS */
number_of_immediate_parent_hosts(host * hst)2202 int number_of_immediate_parent_hosts(host *hst) {
2203 int parents = 0;
2204 host *temp_host = NULL;
2205
2206 if(hst == NULL) {
2207 for(temp_host = host_list; temp_host != NULL;
2208 temp_host = temp_host->next) {
2209 if(is_host_immediate_parent_of_host(hst, temp_host) == TRUE) {
2210 parents++;
2211 }
2212 }
2213 return parents;
2214 }
2215 else {
2216 return hostsmember_elements(hst->parent_hosts);
2217 }
2218 }
2219 #endif
2220
2221 /* tests whether a host is a member of a particular hostgroup */
2222 /* NOTE: This function is only used by the CGIS */
is_host_member_of_hostgroup(hostgroup * group,host * hst)2223 int is_host_member_of_hostgroup(hostgroup *group, host *hst) {
2224 hostsmember *temp_hostsmember = NULL;
2225
2226 if(group == NULL || hst == NULL)
2227 return FALSE;
2228
2229 for(temp_hostsmember = group->members; temp_hostsmember != NULL; temp_hostsmember = temp_hostsmember->next) {
2230 if(temp_hostsmember->host_ptr == hst)
2231 return TRUE;
2232 }
2233
2234 return FALSE;
2235 }
2236
2237
2238 /* tests whether a host is a member of a particular servicegroup */
2239 /* NOTE: This function is only used by the CGIS */
is_host_member_of_servicegroup(servicegroup * group,host * hst)2240 int is_host_member_of_servicegroup(servicegroup *group, host *hst) {
2241 servicesmember *temp_servicesmember = NULL;
2242
2243 if(group == NULL || hst == NULL)
2244 return FALSE;
2245
2246 for(temp_servicesmember = group->members; temp_servicesmember != NULL; temp_servicesmember = temp_servicesmember->next) {
2247 if(temp_servicesmember->service_ptr != NULL && temp_servicesmember->service_ptr->host_ptr == hst)
2248 return TRUE;
2249 }
2250
2251 return FALSE;
2252 }
2253
2254
2255 /* tests whether a service is a member of a particular servicegroup */
2256 /* NOTE: This function is only used by the CGIS */
is_service_member_of_servicegroup(servicegroup * group,service * svc)2257 int is_service_member_of_servicegroup(servicegroup *group, service *svc) {
2258 servicesmember *temp_servicesmember = NULL;
2259
2260 if(group == NULL || svc == NULL)
2261 return FALSE;
2262
2263 for(temp_servicesmember = group->members; temp_servicesmember != NULL; temp_servicesmember = temp_servicesmember->next) {
2264 if(temp_servicesmember->service_ptr == svc)
2265 return TRUE;
2266 }
2267
2268 return FALSE;
2269 }
2270
2271
2272 /*
2273 * tests whether a contact is a member of a particular contactgroup.
2274 * The mk-livestatus eventbroker module uses this, so it must hang
2275 * around until 4.0 to prevent api breakage.
2276 * The cgi's stopped using it quite long ago though, so we need only
2277 * compile it if we're building the core
2278 */
is_contact_member_of_contactgroup(contactgroup * group,contact * cntct)2279 int is_contact_member_of_contactgroup(contactgroup *group, contact *cntct) {
2280 contactsmember *member;
2281
2282 if(!group || !cntct)
2283 return FALSE;
2284
2285 /* search all contacts in this contact group */
2286 for(member = group->members; member; member = member->next) {
2287 if (member->contact_ptr == cntct)
2288 return TRUE;
2289 }
2290
2291 return FALSE;
2292 }
2293
2294 /* tests whether a contact is a contact for a particular host */
is_contact_for_host(host * hst,contact * cntct)2295 int is_contact_for_host(host *hst, contact *cntct) {
2296 contactsmember *temp_contactsmember = NULL;
2297 contactgroupsmember *temp_contactgroupsmember = NULL;
2298 contactgroup *temp_contactgroup = NULL;
2299
2300 if(hst == NULL || cntct == NULL) {
2301 return FALSE;
2302 }
2303
2304 /* search all individual contacts of this host */
2305 for(temp_contactsmember = hst->contacts; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) {
2306 if (temp_contactsmember->contact_ptr == cntct)
2307 return TRUE;
2308 }
2309
2310 /* search all contactgroups of this host */
2311 for(temp_contactgroupsmember = hst->contact_groups; temp_contactgroupsmember != NULL; temp_contactgroupsmember = temp_contactgroupsmember->next) {
2312 temp_contactgroup = temp_contactgroupsmember->group_ptr;
2313 if(is_contact_member_of_contactgroup(temp_contactgroup, cntct))
2314 return TRUE;
2315 }
2316
2317 return FALSE;
2318 }
2319
2320
2321
2322 /* tests whether a contactgroup is a contactgroup for a particular host */
is_contactgroup_for_host(host * hst,contactgroup * group)2323 int is_contactgroup_for_host(host *hst, contactgroup *group) {
2324 contactgroupsmember *temp_contactgroupsmember = NULL;
2325
2326 if(hst == NULL || group == NULL) {
2327 return FALSE;
2328 }
2329
2330 /* search all contactgroups of this host */
2331 for(temp_contactgroupsmember = hst->contact_groups;
2332 temp_contactgroupsmember != NULL;
2333 temp_contactgroupsmember = temp_contactgroupsmember->next) {
2334 if(temp_contactgroupsmember->group_ptr == group) {
2335 return TRUE;
2336 }
2337 }
2338
2339 return FALSE;
2340 }
2341
2342
2343
2344 /* tests whether a contact is an escalated contact for a particular host */
is_escalated_contact_for_host(host * hst,contact * cntct)2345 int is_escalated_contact_for_host(host *hst, contact *cntct) {
2346 hostescalation *temp_hostescalation = NULL;
2347 objectlist *list;
2348
2349 /* search all host escalations */
2350 for(list = hst->escalation_list; list; list = list->next) {
2351 temp_hostescalation = (hostescalation *)list->object_ptr;
2352
2353 if(is_contact_for_host_escalation(temp_hostescalation, cntct) == TRUE) {
2354 return TRUE;
2355 }
2356 }
2357
2358 return FALSE;
2359 }
2360
2361
2362
2363 /* tests whether a contact is an contact for a particular host escalation */
is_contact_for_host_escalation(hostescalation * escalation,contact * cntct)2364 int is_contact_for_host_escalation(hostescalation *escalation, contact *cntct) {
2365 contactsmember *temp_contactsmember = NULL;
2366 contactgroupsmember *temp_contactgroupsmember = NULL;
2367 contactgroup *temp_contactgroup = NULL;
2368
2369 if(escalation == NULL || cntct == NULL) {
2370 return FALSE;
2371 }
2372
2373 /* search all contacts of this host escalation */
2374 for(temp_contactsmember = escalation->contacts;
2375 temp_contactsmember != NULL;
2376 temp_contactsmember = temp_contactsmember->next) {
2377 if(temp_contactsmember->contact_ptr == cntct)
2378 return TRUE;
2379 }
2380
2381 /* search all contactgroups of this host escalation */
2382 for(temp_contactgroupsmember = escalation->contact_groups;
2383 temp_contactgroupsmember != NULL;
2384 temp_contactgroupsmember = temp_contactgroupsmember->next) {
2385 temp_contactgroup = temp_contactgroupsmember->group_ptr;
2386 if(is_contact_member_of_contactgroup(temp_contactgroup, cntct))
2387 return TRUE;
2388 }
2389
2390 return FALSE;
2391 }
2392
2393
2394
2395 /* tests whether a contactgroup is a contactgroup for a particular
2396 host escalation */
is_contactgroup_for_host_escalation(hostescalation * escalation,contactgroup * group)2397 int is_contactgroup_for_host_escalation(hostescalation *escalation,
2398 contactgroup *group) {
2399 contactgroupsmember *temp_contactgroupsmember = NULL;
2400
2401 if(escalation == NULL || group == NULL) {
2402 return FALSE;
2403 }
2404
2405 /* search all contactgroups of this host escalation */
2406 for(temp_contactgroupsmember = escalation->contact_groups;
2407 temp_contactgroupsmember != NULL;
2408 temp_contactgroupsmember = temp_contactgroupsmember->next) {
2409 if(temp_contactgroupsmember->group_ptr == group) {
2410 return TRUE;
2411 }
2412 }
2413
2414 return FALSE;
2415 }
2416
2417
2418
2419 /* tests whether a contact is a contact for a particular service */
is_contact_for_service(service * svc,contact * cntct)2420 int is_contact_for_service(service *svc, contact *cntct) {
2421 contactsmember *temp_contactsmember = NULL;
2422 contactgroupsmember *temp_contactgroupsmember = NULL;
2423 contactgroup *temp_contactgroup = NULL;
2424
2425 if(svc == NULL || cntct == NULL)
2426 return FALSE;
2427
2428 /* search all individual contacts of this service */
2429 for(temp_contactsmember = svc->contacts; temp_contactsmember != NULL; temp_contactsmember = temp_contactsmember->next) {
2430 if(temp_contactsmember->contact_ptr == cntct)
2431 return TRUE;
2432 }
2433
2434 /* search all contactgroups of this service */
2435 for(temp_contactgroupsmember = svc->contact_groups; temp_contactgroupsmember != NULL; temp_contactgroupsmember = temp_contactgroupsmember->next) {
2436 temp_contactgroup = temp_contactgroupsmember->group_ptr;
2437 if(is_contact_member_of_contactgroup(temp_contactgroup, cntct))
2438 return TRUE;
2439
2440 }
2441
2442 return FALSE;
2443 }
2444
2445
2446
2447 /* tests whether a contactgroup is a contactgroup for a particular service */
is_contactgroup_for_service(service * svc,contactgroup * group)2448 int is_contactgroup_for_service(service *svc, contactgroup *group) {
2449 contactgroupsmember *temp_contactgroupsmember = NULL;
2450
2451 if(svc == NULL || group == NULL)
2452 return FALSE;
2453
2454 /* search all contactgroups of this service */
2455 for(temp_contactgroupsmember = svc->contact_groups;
2456 temp_contactgroupsmember != NULL;
2457 temp_contactgroupsmember = temp_contactgroupsmember->next) {
2458 if(temp_contactgroupsmember->group_ptr == group) {
2459 return TRUE;
2460 }
2461 }
2462
2463 return FALSE;
2464 }
2465
2466
2467
2468 /* tests whether a contact is an escalated contact for a particular service */
is_escalated_contact_for_service(service * svc,contact * cntct)2469 int is_escalated_contact_for_service(service *svc, contact *cntct) {
2470 serviceescalation *temp_serviceescalation = NULL;
2471 objectlist *list;
2472
2473 /* search all the service escalations */
2474 for(list = svc->escalation_list; list; list = list->next) {
2475 temp_serviceescalation = (serviceescalation *)list->object_ptr;
2476
2477 if(is_contact_for_service_escalation(temp_serviceescalation,
2478 cntct) == TRUE) {
2479 return TRUE;
2480 }
2481 }
2482
2483 return FALSE;
2484 }
2485
2486
2487
2488 /* tests whether a contact is an contact for a particular service escalation */
is_contact_for_service_escalation(serviceescalation * escalation,contact * cntct)2489 int is_contact_for_service_escalation(serviceescalation *escalation,
2490 contact *cntct) {
2491 contactsmember *temp_contactsmember = NULL;
2492 contactgroupsmember *temp_contactgroupsmember = NULL;
2493 contactgroup *temp_contactgroup = NULL;
2494
2495 /* search all contacts of this service escalation */
2496 for(temp_contactsmember = escalation->contacts;
2497 temp_contactsmember != NULL;
2498 temp_contactsmember = temp_contactsmember->next) {
2499 if(temp_contactsmember->contact_ptr == cntct)
2500 return TRUE;
2501 }
2502
2503 /* search all contactgroups of this service escalation */
2504 for(temp_contactgroupsmember =escalation->contact_groups;
2505 temp_contactgroupsmember != NULL;
2506 temp_contactgroupsmember = temp_contactgroupsmember->next) {
2507 temp_contactgroup = temp_contactgroupsmember->group_ptr;
2508 if(is_contact_member_of_contactgroup(temp_contactgroup, cntct))
2509 return TRUE;
2510 }
2511
2512 return FALSE;
2513 }
2514
2515
2516
2517 /* tests whether a contactgroup is a contactgroup for a particular
2518 service escalation */
is_contactgroup_for_service_escalation(serviceescalation * escalation,contactgroup * group)2519 int is_contactgroup_for_service_escalation(serviceescalation *escalation,
2520 contactgroup *group) {
2521 contactgroupsmember *temp_contactgroupsmember = NULL;
2522
2523 if(escalation == NULL || group == NULL) {
2524 return FALSE;
2525 }
2526
2527 /* search all contactgroups of this service escalation */
2528 for(temp_contactgroupsmember = escalation->contact_groups;
2529 temp_contactgroupsmember != NULL;
2530 temp_contactgroupsmember = temp_contactgroupsmember->next) {
2531 if(temp_contactgroupsmember->group_ptr == group) {
2532 return TRUE;
2533 }
2534 }
2535
2536 return FALSE;
2537 }
2538
2539
2540
2541 /******************************************************************/
2542 /******************* OBJECT DELETION FUNCTIONS ********************/
2543 /******************************************************************/
2544
2545
2546 /* free all allocated memory for objects */
free_object_data(void)2547 int free_object_data(void) {
2548 daterange *this_daterange = NULL;
2549 daterange *next_daterange = NULL;
2550 timerange *this_timerange = NULL;
2551 timerange *next_timerange = NULL;
2552 timeperiodexclusion *this_timeperiodexclusion = NULL;
2553 timeperiodexclusion *next_timeperiodexclusion = NULL;
2554 hostsmember *this_hostsmember = NULL;
2555 hostsmember *next_hostsmember = NULL;
2556 servicesmember *this_servicesmember = NULL;
2557 servicesmember *next_servicesmember = NULL;
2558 contactsmember *this_contactsmember = NULL;
2559 contactsmember *next_contactsmember = NULL;
2560 contactgroupsmember *this_contactgroupsmember = NULL;
2561 contactgroupsmember *next_contactgroupsmember = NULL;
2562 customvariablesmember *this_customvariablesmember = NULL;
2563 customvariablesmember *next_customvariablesmember = NULL;
2564 commandsmember *this_commandsmember = NULL;
2565 commandsmember *next_commandsmember = NULL;
2566 unsigned int i = 0, x = 0;
2567
2568
2569 /*
2570 * kill off hash tables so lingering modules don't look stuff up
2571 * while we're busy removing it.
2572 */
2573 for (i = 0; i < ARRAY_SIZE(object_hash_tables); i++) {
2574 dkhash_table *t = object_hash_tables[i];
2575 object_hash_tables[i] = NULL;
2576 dkhash_destroy(t);
2577 }
2578
2579 /**** free memory for the timeperiod list ****/
2580 for (i = 0; i < num_objects.timeperiods; i++) {
2581 timeperiod *this_timeperiod = timeperiod_ary[i];
2582
2583 /* free the exception time ranges contained in this timeperiod */
2584 for(x = 0; x < DATERANGE_TYPES; x++) {
2585
2586 for(this_daterange = this_timeperiod->exceptions[x]; this_daterange != NULL; this_daterange = next_daterange) {
2587 next_daterange = this_daterange->next;
2588 for(this_timerange = this_daterange->times; this_timerange != NULL; this_timerange = next_timerange) {
2589 next_timerange = this_timerange->next;
2590 my_free(this_timerange);
2591 }
2592 my_free(this_daterange);
2593 }
2594 }
2595
2596 /* free the day time ranges contained in this timeperiod */
2597 for(x = 0; x < 7; x++) {
2598
2599 for(this_timerange = this_timeperiod->days[x]; this_timerange != NULL; this_timerange = next_timerange) {
2600 next_timerange = this_timerange->next;
2601 my_free(this_timerange);
2602 }
2603 }
2604
2605 /* free exclusions */
2606 for(this_timeperiodexclusion = this_timeperiod->exclusions; this_timeperiodexclusion != NULL; this_timeperiodexclusion = next_timeperiodexclusion) {
2607 next_timeperiodexclusion = this_timeperiodexclusion->next;
2608 my_free(this_timeperiodexclusion->timeperiod_name);
2609 my_free(this_timeperiodexclusion);
2610 }
2611
2612 if (this_timeperiod->alias != this_timeperiod->name)
2613 my_free(this_timeperiod->alias);
2614 my_free(this_timeperiod->name);
2615 my_free(this_timeperiod);
2616 }
2617
2618 /* reset pointers */
2619 my_free(timeperiod_ary);
2620
2621
2622 /**** free memory for the host list ****/
2623 for (i = 0; i < num_objects.hosts; i++) {
2624 host *this_host = host_ary[i];
2625
2626 /* free memory for parent hosts */
2627 this_hostsmember = this_host->parent_hosts;
2628 while(this_hostsmember != NULL) {
2629 next_hostsmember = this_hostsmember->next;
2630 my_free(this_hostsmember->host_name);
2631 my_free(this_hostsmember);
2632 this_hostsmember = next_hostsmember;
2633 }
2634
2635 /* free memory for child host links */
2636 this_hostsmember = this_host->child_hosts;
2637 while(this_hostsmember != NULL) {
2638 next_hostsmember = this_hostsmember->next;
2639 my_free(this_hostsmember);
2640 this_hostsmember = next_hostsmember;
2641 }
2642
2643 /* free memory for service links */
2644 this_servicesmember = this_host->services;
2645 while(this_servicesmember != NULL) {
2646 next_servicesmember = this_servicesmember->next;
2647 my_free(this_servicesmember);
2648 this_servicesmember = next_servicesmember;
2649 }
2650
2651 /* free memory for contact groups */
2652 this_contactgroupsmember = this_host->contact_groups;
2653 while(this_contactgroupsmember != NULL) {
2654 next_contactgroupsmember = this_contactgroupsmember->next;
2655 my_free(this_contactgroupsmember);
2656 this_contactgroupsmember = next_contactgroupsmember;
2657 }
2658
2659 /* free memory for contacts */
2660 this_contactsmember = this_host->contacts;
2661 while(this_contactsmember != NULL) {
2662 next_contactsmember = this_contactsmember->next;
2663 my_free(this_contactsmember);
2664 this_contactsmember = next_contactsmember;
2665 }
2666
2667 /* free memory for custom variables */
2668 this_customvariablesmember = this_host->custom_variables;
2669 while(this_customvariablesmember != NULL) {
2670 next_customvariablesmember = this_customvariablesmember->next;
2671 my_free(this_customvariablesmember->variable_name);
2672 my_free(this_customvariablesmember->variable_value);
2673 my_free(this_customvariablesmember);
2674 this_customvariablesmember = next_customvariablesmember;
2675 }
2676
2677 if(this_host->display_name != this_host->name)
2678 my_free(this_host->display_name);
2679 if(this_host->alias != this_host->name)
2680 my_free(this_host->alias);
2681 if(this_host->address != this_host->name)
2682 my_free(this_host->address);
2683 my_free(this_host->name);
2684 my_free(this_host->check_period);
2685 my_free(this_host->notification_period);
2686 #ifdef NSCORE
2687 my_free(this_host->plugin_output);
2688 my_free(this_host->long_plugin_output);
2689 my_free(this_host->perf_data);
2690 #endif
2691 free_objectlist(&this_host->hostgroups_ptr);
2692 free_objectlist(&this_host->notify_deps);
2693 free_objectlist(&this_host->exec_deps);
2694 free_objectlist(&this_host->escalation_list);
2695 my_free(this_host->check_command);
2696 my_free(this_host->event_handler);
2697 my_free(this_host->notes);
2698 my_free(this_host->notes_url);
2699 my_free(this_host->action_url);
2700 my_free(this_host->icon_image);
2701 my_free(this_host->icon_image_alt);
2702 my_free(this_host->vrml_image);
2703 my_free(this_host->statusmap_image);
2704 my_free(this_host);
2705 }
2706
2707 /* reset pointers */
2708 my_free(host_ary);
2709
2710
2711 /**** free memory for the host group list ****/
2712 for (i = 0; i < num_objects.hostgroups; i++) {
2713 hostgroup *this_hostgroup = hostgroup_ary[i];
2714
2715 /* free memory for the group members */
2716 this_hostsmember = this_hostgroup->members;
2717 while(this_hostsmember != NULL) {
2718 next_hostsmember = this_hostsmember->next;
2719 my_free(this_hostsmember);
2720 this_hostsmember = next_hostsmember;
2721 }
2722
2723 if (this_hostgroup->alias != this_hostgroup->group_name)
2724 my_free(this_hostgroup->alias);
2725 my_free(this_hostgroup->group_name);
2726 my_free(this_hostgroup->notes);
2727 my_free(this_hostgroup->notes_url);
2728 my_free(this_hostgroup->action_url);
2729 my_free(this_hostgroup);
2730 }
2731
2732 /* reset pointers */
2733 my_free(hostgroup_ary);
2734
2735 /**** free memory for the service group list ****/
2736 for (i = 0; i < num_objects.servicegroups; i++) {
2737 servicegroup *this_servicegroup = servicegroup_ary[i];
2738
2739 /* free memory for the group members */
2740 this_servicesmember = this_servicegroup->members;
2741 while(this_servicesmember != NULL) {
2742 next_servicesmember = this_servicesmember->next;
2743 my_free(this_servicesmember);
2744 this_servicesmember = next_servicesmember;
2745 }
2746
2747 if (this_servicegroup->alias != this_servicegroup->group_name)
2748 my_free(this_servicegroup->alias);
2749 my_free(this_servicegroup->group_name);
2750 my_free(this_servicegroup->notes);
2751 my_free(this_servicegroup->notes_url);
2752 my_free(this_servicegroup->action_url);
2753 my_free(this_servicegroup);
2754 }
2755
2756 /* reset pointers */
2757 my_free(servicegroup_ary);
2758
2759 /**** free memory for the contact list ****/
2760 for (i = 0; i < num_objects.contacts; i++) {
2761 int j;
2762 contact *this_contact = contact_ary[i];
2763
2764 /* free memory for the host notification commands */
2765 this_commandsmember = this_contact->host_notification_commands;
2766 while(this_commandsmember != NULL) {
2767 next_commandsmember = this_commandsmember->next;
2768 if(this_commandsmember->command != NULL)
2769 my_free(this_commandsmember->command);
2770 my_free(this_commandsmember);
2771 this_commandsmember = next_commandsmember;
2772 }
2773
2774 /* free memory for the service notification commands */
2775 this_commandsmember = this_contact->service_notification_commands;
2776 while(this_commandsmember != NULL) {
2777 next_commandsmember = this_commandsmember->next;
2778 if(this_commandsmember->command != NULL)
2779 my_free(this_commandsmember->command);
2780 my_free(this_commandsmember);
2781 this_commandsmember = next_commandsmember;
2782 }
2783
2784 /* free memory for custom variables */
2785 this_customvariablesmember = this_contact->custom_variables;
2786 while(this_customvariablesmember != NULL) {
2787 next_customvariablesmember = this_customvariablesmember->next;
2788 my_free(this_customvariablesmember->variable_name);
2789 my_free(this_customvariablesmember->variable_value);
2790 my_free(this_customvariablesmember);
2791 this_customvariablesmember = next_customvariablesmember;
2792 }
2793
2794 if (this_contact->alias != this_contact->name)
2795 my_free(this_contact->alias);
2796 my_free(this_contact->name);
2797 my_free(this_contact->email);
2798 my_free(this_contact->pager);
2799 my_free(this_contact->host_notification_period);
2800 my_free(this_contact->service_notification_period);
2801 for(j = 0; j < MAX_CONTACT_ADDRESSES; j++)
2802 my_free(this_contact->address[j]);
2803
2804 free_objectlist(&this_contact->contactgroups_ptr);
2805 my_free(this_contact);
2806 }
2807
2808 /* reset pointers */
2809 my_free(contact_ary);
2810
2811
2812 /**** free memory for the contact group list ****/
2813 for (i = 0; i < num_objects.contactgroups; i++) {
2814 contactgroup *this_contactgroup = contactgroup_ary[i];
2815
2816 /* free memory for the group members */
2817 this_contactsmember = this_contactgroup->members;
2818 while(this_contactsmember != NULL) {
2819 next_contactsmember = this_contactsmember->next;
2820 my_free(this_contactsmember);
2821 this_contactsmember = next_contactsmember;
2822 }
2823
2824 if (this_contactgroup->alias != this_contactgroup->group_name)
2825 my_free(this_contactgroup->alias);
2826 my_free(this_contactgroup->group_name);
2827 my_free(this_contactgroup);
2828 }
2829
2830 /* reset pointers */
2831 my_free(contactgroup_ary);
2832
2833
2834 /**** free memory for the service list ****/
2835 for (i = 0; i < num_objects.services; i++) {
2836 service *this_service = service_ary[i];
2837
2838 /* free memory for contact groups */
2839 this_contactgroupsmember = this_service->contact_groups;
2840 while(this_contactgroupsmember != NULL) {
2841 next_contactgroupsmember = this_contactgroupsmember->next;
2842 my_free(this_contactgroupsmember);
2843 this_contactgroupsmember = next_contactgroupsmember;
2844 }
2845
2846 /* free memory for contacts */
2847 this_contactsmember = this_service->contacts;
2848 while(this_contactsmember != NULL) {
2849 next_contactsmember = this_contactsmember->next;
2850 my_free(this_contactsmember);
2851 this_contactsmember = next_contactsmember;
2852 }
2853
2854 /* free memory for custom variables */
2855 this_customvariablesmember = this_service->custom_variables;
2856 while(this_customvariablesmember != NULL) {
2857 next_customvariablesmember = this_customvariablesmember->next;
2858 my_free(this_customvariablesmember->variable_name);
2859 my_free(this_customvariablesmember->variable_value);
2860 my_free(this_customvariablesmember);
2861 this_customvariablesmember = next_customvariablesmember;
2862 }
2863
2864 if(this_service->display_name != this_service->description)
2865 my_free(this_service->display_name);
2866 my_free(this_service->description);
2867 my_free(this_service->check_command);
2868 my_free(this_service->check_period);
2869 my_free(this_service->notification_period);
2870 #ifdef NSCORE
2871 my_free(this_service->plugin_output);
2872 my_free(this_service->long_plugin_output);
2873 my_free(this_service->perf_data);
2874
2875 my_free(this_service->event_handler_args);
2876 my_free(this_service->check_command_args);
2877 #endif
2878
2879 free_objectlist(&this_service->servicegroups_ptr);
2880 free_objectlist(&this_service->notify_deps);
2881 free_objectlist(&this_service->exec_deps);
2882 free_objectlist(&this_service->escalation_list);
2883 my_free(this_service->event_handler);
2884 my_free(this_service->notes);
2885 my_free(this_service->notes_url);
2886 my_free(this_service->action_url);
2887 my_free(this_service->icon_image);
2888 my_free(this_service->icon_image_alt);
2889 my_free(this_service);
2890 }
2891
2892 /* reset pointers */
2893 my_free(service_ary);
2894
2895
2896 /**** free command memory ****/
2897 for (i = 0; i < num_objects.commands; i++) {
2898 command *this_command = command_ary[i];
2899 my_free(this_command->name);
2900 my_free(this_command->command_line);
2901 my_free(this_command);
2902 }
2903
2904 /* reset pointers */
2905 my_free(command_ary);
2906
2907
2908 /**** free service escalation memory ****/
2909 for (i = 0; i < num_objects.serviceescalations; i++) {
2910 serviceescalation *this_serviceescalation = serviceescalation_ary[i];
2911
2912 /* free memory for the contact group members */
2913 this_contactgroupsmember = this_serviceescalation->contact_groups;
2914 while(this_contactgroupsmember != NULL) {
2915 next_contactgroupsmember = this_contactgroupsmember->next;
2916 my_free(this_contactgroupsmember);
2917 this_contactgroupsmember = next_contactgroupsmember;
2918 }
2919
2920 /* free memory for contacts */
2921 this_contactsmember = this_serviceescalation->contacts;
2922 while(this_contactsmember != NULL) {
2923 next_contactsmember = this_contactsmember->next;
2924 my_free(this_contactsmember);
2925 this_contactsmember = next_contactsmember;
2926 }
2927 my_free(this_serviceescalation);
2928 }
2929
2930 /* reset pointers */
2931 my_free(serviceescalation_ary);
2932
2933
2934 /**** free service dependency memory ****/
2935 if (servicedependency_ary) {
2936 for(i = 0; i < num_objects.servicedependencies; i++)
2937 my_free(servicedependency_ary[i]);
2938 my_free(servicedependency_ary);
2939 }
2940
2941
2942 /**** free host dependency memory ****/
2943 if (hostdependency_ary) {
2944 for(i = 0; i < num_objects.hostdependencies; i++)
2945 my_free(hostdependency_ary[i]);
2946 my_free(hostdependency_ary);
2947 }
2948
2949
2950 /**** free host escalation memory ****/
2951 for (i = 0; i < num_objects.hostescalations; i++) {
2952 hostescalation *this_hostescalation = hostescalation_ary[i];
2953
2954 /* free memory for the contact group members */
2955 this_contactgroupsmember = this_hostescalation->contact_groups;
2956 while(this_contactgroupsmember != NULL) {
2957 next_contactgroupsmember = this_contactgroupsmember->next;
2958 my_free(this_contactgroupsmember);
2959 this_contactgroupsmember = next_contactgroupsmember;
2960 }
2961
2962 /* free memory for contacts */
2963 this_contactsmember = this_hostescalation->contacts;
2964 while(this_contactsmember != NULL) {
2965 next_contactsmember = this_contactsmember->next;
2966 my_free(this_contactsmember);
2967 this_contactsmember = next_contactsmember;
2968 }
2969 my_free(this_hostescalation);
2970 }
2971
2972 /* reset pointers */
2973 my_free(hostescalation_ary);
2974
2975 /* we no longer have any objects */
2976 memset(&num_objects, 0, sizeof(num_objects));
2977
2978 return OK;
2979 }
2980
2981
2982
2983 /******************************************************************/
2984 /*********************** CACHE FUNCTIONS **************************/
2985 /******************************************************************/
2986
2987 #ifndef NSCGI
timerange2str(const timerange * tr)2988 static const char *timerange2str(const timerange *tr)
2989 {
2990 static char str[12];
2991 int sh, sm, eh, em;
2992
2993 if(!tr)
2994 return "";
2995 sh = tr->range_start / 3600;
2996 sm = (tr->range_start / 60) % 60;
2997 eh = tr->range_end / 3600;
2998 em = (tr->range_end / 60) % 60;
2999 sprintf(str, "%02d:%02d-%02d:%02d", sh, sm, eh, em);
3000 return str;
3001 }
3002
fcache_contactlist(FILE * fp,const char * prefix,contactsmember * list)3003 void fcache_contactlist(FILE *fp, const char *prefix, contactsmember *list)
3004 {
3005 if(list) {
3006 contactsmember *l;
3007 fprintf(fp, "%s", prefix);
3008 for(l = list; l; l = l->next)
3009 fprintf(fp, "%s%c", l->contact_name, l->next ? ',' : '\n');
3010 }
3011 }
3012
fcache_contactgrouplist(FILE * fp,const char * prefix,contactgroupsmember * list)3013 void fcache_contactgrouplist(FILE *fp, const char *prefix, contactgroupsmember *list)
3014 {
3015 if(list) {
3016 contactgroupsmember *l;
3017 fprintf(fp, "%s", prefix);
3018 for(l = list; l; l = l->next)
3019 fprintf(fp, "%s%c", l->group_name, l->next ? ',' : '\n');
3020 }
3021 }
3022
fcache_hostlist(FILE * fp,const char * prefix,hostsmember * list)3023 void fcache_hostlist(FILE *fp, const char *prefix, hostsmember *list)
3024 {
3025 if(list) {
3026 hostsmember *l;
3027 fprintf(fp, "%s", prefix);
3028 for(l = list; l; l = l->next)
3029 fprintf(fp, "%s%c", l->host_name, l->next ? ',' : '\n');
3030 }
3031 }
3032
fcache_customvars(FILE * fp,customvariablesmember * cvlist)3033 void fcache_customvars(FILE *fp, customvariablesmember *cvlist)
3034 {
3035 if(cvlist) {
3036 customvariablesmember *l;
3037 for(l = cvlist; l; l = l->next)
3038 fprintf(fp, "\t_%s\t%s\n", l->variable_name, (l->variable_value == NULL) ? XODTEMPLATE_NULL : l->variable_value);
3039 }
3040 }
3041
fcache_timeperiod(FILE * fp,timeperiod * temp_timeperiod)3042 void fcache_timeperiod(FILE *fp, timeperiod *temp_timeperiod)
3043 {
3044 const char *days[7] = {"sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"};
3045 const char *months[12] = {"january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"};
3046 daterange *temp_daterange;
3047 timerange *tr;
3048 register int x;
3049
3050 fprintf(fp, "define timeperiod {\n");
3051 fprintf(fp, "\ttimeperiod_name\t%s\n", temp_timeperiod->name);
3052 if(temp_timeperiod->alias)
3053 fprintf(fp, "\talias\t%s\n", temp_timeperiod->alias);
3054
3055 if(temp_timeperiod->exclusions) {
3056 timeperiodexclusion *exclude;
3057 fprintf(fp, "\texclude\t");
3058 for(exclude = temp_timeperiod->exclusions; exclude; exclude = exclude->next) {
3059 fprintf(fp, "%s%c", exclude->timeperiod_name, exclude->next ? ',' : '\n');
3060 }
3061 }
3062
3063 for(x = 0; x < DATERANGE_TYPES; x++) {
3064 for(temp_daterange = temp_timeperiod->exceptions[x]; temp_daterange != NULL; temp_daterange = temp_daterange->next) {
3065
3066 /* skip null entries */
3067 if(temp_daterange->times == NULL)
3068 continue;
3069
3070 switch(temp_daterange->type) {
3071 case DATERANGE_CALENDAR_DATE:
3072 fprintf(fp, "\t%d-%02d-%02d", temp_daterange->syear, temp_daterange->smon + 1, temp_daterange->smday);
3073 if((temp_daterange->smday != temp_daterange->emday) || (temp_daterange->smon != temp_daterange->emon) || (temp_daterange->syear != temp_daterange->eyear))
3074 fprintf(fp, " - %d-%02d-%02d", temp_daterange->eyear, temp_daterange->emon + 1, temp_daterange->emday);
3075 if(temp_daterange->skip_interval > 1)
3076 fprintf(fp, " / %d", temp_daterange->skip_interval);
3077 break;
3078 case DATERANGE_MONTH_DATE:
3079 fprintf(fp, "\t%s %d", months[temp_daterange->smon], temp_daterange->smday);
3080 if((temp_daterange->smon != temp_daterange->emon) || (temp_daterange->smday != temp_daterange->emday)) {
3081 fprintf(fp, " - %s %d", months[temp_daterange->emon], temp_daterange->emday);
3082 if(temp_daterange->skip_interval > 1)
3083 fprintf(fp, " / %d", temp_daterange->skip_interval);
3084 }
3085 break;
3086 case DATERANGE_MONTH_DAY:
3087 fprintf(fp, "\tday %d", temp_daterange->smday);
3088 if(temp_daterange->smday != temp_daterange->emday) {
3089 fprintf(fp, " - %d", temp_daterange->emday);
3090 if(temp_daterange->skip_interval > 1)
3091 fprintf(fp, " / %d", temp_daterange->skip_interval);
3092 }
3093 break;
3094 case DATERANGE_MONTH_WEEK_DAY:
3095 fprintf(fp, "\t%s %d %s", days[temp_daterange->swday], temp_daterange->swday_offset, months[temp_daterange->smon]);
3096 if((temp_daterange->smon != temp_daterange->emon) || (temp_daterange->swday != temp_daterange->ewday) || (temp_daterange->swday_offset != temp_daterange->ewday_offset)) {
3097 fprintf(fp, " - %s %d %s", days[temp_daterange->ewday], temp_daterange->ewday_offset, months[temp_daterange->emon]);
3098 if(temp_daterange->skip_interval > 1)
3099 fprintf(fp, " / %d", temp_daterange->skip_interval);
3100 }
3101 break;
3102 case DATERANGE_WEEK_DAY:
3103 fprintf(fp, "\t%s %d", days[temp_daterange->swday], temp_daterange->swday_offset);
3104 if((temp_daterange->swday != temp_daterange->ewday) || (temp_daterange->swday_offset != temp_daterange->ewday_offset)) {
3105 fprintf(fp, " - %s %d", days[temp_daterange->ewday], temp_daterange->ewday_offset);
3106 if(temp_daterange->skip_interval > 1)
3107 fprintf(fp, " / %d", temp_daterange->skip_interval);
3108 }
3109 break;
3110 default:
3111 break;
3112 }
3113
3114 fputc('\t', fp);
3115 for(tr = temp_daterange->times; tr; tr = tr->next) {
3116 fprintf(fp, "%s%c", timerange2str(tr), tr->next ? ',' : '\n');
3117 }
3118 }
3119 }
3120 for(x = 0; x < 7; x++) {
3121 /* skip null entries */
3122 if(temp_timeperiod->days[x] == NULL)
3123 continue;
3124
3125 fprintf(fp, "\t%s\t", days[x]);
3126 for(tr = temp_timeperiod->days[x]; tr; tr = tr->next) {
3127 fprintf(fp, "%s%c", timerange2str(tr), tr->next ? ',' : '\n');
3128 }
3129 }
3130 fprintf(fp, "\t}\n\n");
3131 }
3132
fcache_command(FILE * fp,command * temp_command)3133 void fcache_command(FILE *fp, command *temp_command)
3134 {
3135 fprintf(fp, "define command {\n\tcommand_name\t%s\n\tcommand_line\t%s\n\t}\n\n",
3136 temp_command->name, temp_command->command_line);
3137 }
3138
fcache_contactgroup(FILE * fp,contactgroup * temp_contactgroup)3139 void fcache_contactgroup(FILE *fp, contactgroup *temp_contactgroup)
3140 {
3141 fprintf(fp, "define contactgroup {\n");
3142 fprintf(fp, "\tcontactgroup_name\t%s\n", temp_contactgroup->group_name);
3143 if(temp_contactgroup->alias)
3144 fprintf(fp, "\talias\t%s\n", temp_contactgroup->alias);
3145 fcache_contactlist(fp, "\tmembers\t", temp_contactgroup->members);
3146 fprintf(fp, "\t}\n\n");
3147 }
3148
fcache_hostgroup(FILE * fp,hostgroup * temp_hostgroup)3149 void fcache_hostgroup(FILE *fp, hostgroup *temp_hostgroup)
3150 {
3151 fprintf(fp, "define hostgroup {\n");
3152 fprintf(fp, "\thostgroup_name\t%s\n", temp_hostgroup->group_name);
3153 if(temp_hostgroup->alias)
3154 fprintf(fp, "\talias\t%s\n", temp_hostgroup->alias);
3155 if(temp_hostgroup->members) {
3156 hostsmember *list;
3157 fprintf(fp, "\tmembers\t");
3158 for(list = temp_hostgroup->members; list; list = list->next)
3159 fprintf(fp, "%s%c", list->host_name, list->next ? ',' : '\n');
3160 }
3161 if(temp_hostgroup->notes)
3162 fprintf(fp, "\tnotes\t%s\n", temp_hostgroup->notes);
3163 if(temp_hostgroup->notes_url)
3164 fprintf(fp, "\tnotes_url\t%s\n", temp_hostgroup->notes_url);
3165 if(temp_hostgroup->action_url)
3166 fprintf(fp, "\taction_url\t%s\n", temp_hostgroup->action_url);
3167 fprintf(fp, "\t}\n\n");
3168 }
3169
fcache_servicegroup(FILE * fp,servicegroup * temp_servicegroup)3170 void fcache_servicegroup(FILE *fp, servicegroup *temp_servicegroup)
3171 {
3172 fprintf(fp, "define servicegroup {\n");
3173 fprintf(fp, "\tservicegroup_name\t%s\n", temp_servicegroup->group_name);
3174 if(temp_servicegroup->alias)
3175 fprintf(fp, "\talias\t%s\n", temp_servicegroup->alias);
3176 if(temp_servicegroup->members) {
3177 servicesmember *list;
3178 fprintf(fp, "\tmembers\t");
3179 for(list = temp_servicegroup->members; list; list = list->next) {
3180 service *s = list->service_ptr;
3181 fprintf(fp, "%s,%s%c", s->host_name, s->description, list->next ? ',' : '\n');
3182 }
3183 }
3184 if(temp_servicegroup->notes)
3185 fprintf(fp, "\tnotes\t%s\n", temp_servicegroup->notes);
3186 if(temp_servicegroup->notes_url)
3187 fprintf(fp, "\tnotes_url\t%s\n", temp_servicegroup->notes_url);
3188 if(temp_servicegroup->action_url)
3189 fprintf(fp, "\taction_url\t%s\n", temp_servicegroup->action_url);
3190 fprintf(fp, "\t}\n\n");
3191 }
3192
fcache_contact(FILE * fp,contact * temp_contact)3193 void fcache_contact(FILE *fp, contact *temp_contact)
3194 {
3195 commandsmember *list;
3196 int x;
3197
3198 fprintf(fp, "define contact {\n");
3199 fprintf(fp, "\tcontact_name\t%s\n", temp_contact->name);
3200 if(temp_contact->alias)
3201 fprintf(fp, "\talias\t%s\n", temp_contact->alias);
3202 if(temp_contact->service_notification_period)
3203 fprintf(fp, "\tservice_notification_period\t%s\n", temp_contact->service_notification_period);
3204 if(temp_contact->host_notification_period)
3205 fprintf(fp, "\thost_notification_period\t%s\n", temp_contact->host_notification_period);
3206 fprintf(fp, "\tservice_notification_options\t%s\n", opts2str(temp_contact->service_notification_options, service_flag_map, 'r'));
3207 fprintf(fp, "\thost_notification_options\t%s\n", opts2str(temp_contact->host_notification_options, host_flag_map, 'r'));
3208 if(temp_contact->service_notification_commands) {
3209 fprintf(fp, "\tservice_notification_commands\t");
3210 for(list = temp_contact->service_notification_commands; list; list = list->next) {
3211 fprintf(fp, "%s%c", list->command, list->next ? ',' : '\n');
3212 }
3213 }
3214 if(temp_contact->host_notification_commands) {
3215 fprintf(fp, "\thost_notification_commands\t");
3216 for(list = temp_contact->host_notification_commands; list; list = list->next) {
3217 fprintf(fp, "%s%c", list->command, list->next ? ',' : '\n');
3218 }
3219 }
3220 if(temp_contact->email)
3221 fprintf(fp, "\temail\t%s\n", temp_contact->email);
3222 if(temp_contact->pager)
3223 fprintf(fp, "\tpager\t%s\n", temp_contact->pager);
3224 for(x = 0; x < MAX_XODTEMPLATE_CONTACT_ADDRESSES; x++) {
3225 if(temp_contact->address[x])
3226 fprintf(fp, "\taddress%d\t%s\n", x + 1, temp_contact->address[x]);
3227 }
3228 fprintf(fp, "\tminimum_importance\t%u\n", temp_contact->minimum_value);
3229 fprintf(fp, "\thost_notifications_enabled\t%d\n", temp_contact->host_notifications_enabled);
3230 fprintf(fp, "\tservice_notifications_enabled\t%d\n", temp_contact->service_notifications_enabled);
3231 fprintf(fp, "\tcan_submit_commands\t%d\n", temp_contact->can_submit_commands);
3232 fprintf(fp, "\tretain_status_information\t%d\n", temp_contact->retain_status_information);
3233 fprintf(fp, "\tretain_nonstatus_information\t%d\n", temp_contact->retain_nonstatus_information);
3234
3235 /* custom variables */
3236 fcache_customvars(fp, temp_contact->custom_variables);
3237 fprintf(fp, "\t}\n\n");
3238 }
3239
fcache_host(FILE * fp,host * temp_host)3240 void fcache_host(FILE *fp, host *temp_host)
3241 {
3242 fprintf(fp, "define host {\n");
3243 fprintf(fp, "\thost_name\t%s\n", temp_host->name);
3244 if(temp_host->display_name != temp_host->name)
3245 fprintf(fp, "\tdisplay_name\t%s\n", temp_host->display_name);
3246 if(temp_host->alias)
3247 fprintf(fp, "\talias\t%s\n", temp_host->alias);
3248 if(temp_host->address)
3249 fprintf(fp, "\taddress\t%s\n", temp_host->address);
3250 fcache_hostlist(fp, "\tparents\t", temp_host->parent_hosts);
3251 if(temp_host->check_period)
3252 fprintf(fp, "\tcheck_period\t%s\n", temp_host->check_period);
3253 if(temp_host->check_command)
3254 fprintf(fp, "\tcheck_command\t%s\n", temp_host->check_command);
3255 if(temp_host->event_handler)
3256 fprintf(fp, "\tevent_handler\t%s\n", temp_host->event_handler);
3257 fcache_contactlist(fp, "\tcontacts\t", temp_host->contacts);
3258 fcache_contactgrouplist(fp, "\tcontact_groups\t", temp_host->contact_groups);
3259 if(temp_host->notification_period)
3260 fprintf(fp, "\tnotification_period\t%s\n", temp_host->notification_period);
3261 fprintf(fp, "\tinitial_state\t");
3262 if(temp_host->initial_state == HOST_DOWN)
3263 fprintf(fp, "d\n");
3264 else if(temp_host->initial_state == HOST_UNREACHABLE)
3265 fprintf(fp, "u\n");
3266 else
3267 fprintf(fp, "o\n");
3268 fprintf(fp, "\timportance\t%u\n", temp_host->hourly_value);
3269 fprintf(fp, "\tcheck_interval\t%f\n", temp_host->check_interval);
3270 fprintf(fp, "\tretry_interval\t%f\n", temp_host->retry_interval);
3271 fprintf(fp, "\tmax_check_attempts\t%d\n", temp_host->max_attempts);
3272 fprintf(fp, "\tactive_checks_enabled\t%d\n", temp_host->checks_enabled);
3273 fprintf(fp, "\tpassive_checks_enabled\t%d\n", temp_host->accept_passive_checks);
3274 fprintf(fp, "\tobsess\t%d\n", temp_host->obsess);
3275 fprintf(fp, "\tevent_handler_enabled\t%d\n", temp_host->event_handler_enabled);
3276 fprintf(fp, "\tlow_flap_threshold\t%f\n", temp_host->low_flap_threshold);
3277 fprintf(fp, "\thigh_flap_threshold\t%f\n", temp_host->high_flap_threshold);
3278 fprintf(fp, "\tflap_detection_enabled\t%d\n", temp_host->flap_detection_enabled);
3279 fprintf(fp, "\tflap_detection_options\t%s\n", opts2str(temp_host->flap_detection_options, host_flag_map, 'u'));
3280 fprintf(fp, "\tfreshness_threshold\t%d\n", temp_host->freshness_threshold);
3281 fprintf(fp, "\tcheck_freshness\t%d\n", temp_host->check_freshness);
3282 fprintf(fp, "\tnotification_options\t%s\n", opts2str(temp_host->notification_options, host_flag_map, 'r'));
3283 fprintf(fp, "\tnotifications_enabled\t%d\n", temp_host->notifications_enabled);
3284 fprintf(fp, "\tnotification_interval\t%f\n", temp_host->notification_interval);
3285 fprintf(fp, "\tfirst_notification_delay\t%f\n", temp_host->first_notification_delay);
3286 fprintf(fp, "\tstalking_options\t%s\n", opts2str(temp_host->stalking_options, host_flag_map, 'u'));
3287 fprintf(fp, "\tprocess_perf_data\t%d\n", temp_host->process_performance_data);
3288 if(temp_host->icon_image)
3289 fprintf(fp, "\ticon_image\t%s\n", temp_host->icon_image);
3290 if(temp_host->icon_image_alt)
3291 fprintf(fp, "\ticon_image_alt\t%s\n", temp_host->icon_image_alt);
3292 if(temp_host->vrml_image)
3293 fprintf(fp, "\tvrml_image\t%s\n", temp_host->vrml_image);
3294 if(temp_host->statusmap_image)
3295 fprintf(fp, "\tstatusmap_image\t%s\n", temp_host->statusmap_image);
3296 if(temp_host->have_2d_coords == TRUE)
3297 fprintf(fp, "\t2d_coords\t%d,%d\n", temp_host->x_2d, temp_host->y_2d);
3298 if(temp_host->have_3d_coords == TRUE)
3299 fprintf(fp, "\t3d_coords\t%f,%f,%f\n", temp_host->x_3d, temp_host->y_3d, temp_host->z_3d);
3300 if(temp_host->notes)
3301 fprintf(fp, "\tnotes\t%s\n", temp_host->notes);
3302 if(temp_host->notes_url)
3303 fprintf(fp, "\tnotes_url\t%s\n", temp_host->notes_url);
3304 if(temp_host->action_url)
3305 fprintf(fp, "\taction_url\t%s\n", temp_host->action_url);
3306 fprintf(fp, "\tretain_status_information\t%d\n", temp_host->retain_status_information);
3307 fprintf(fp, "\tretain_nonstatus_information\t%d\n", temp_host->retain_nonstatus_information);
3308
3309 /* custom variables */
3310 fcache_customvars(fp, temp_host->custom_variables);
3311 fprintf(fp, "\t}\n\n");
3312 }
3313
fcache_service(FILE * fp,service * temp_service)3314 void fcache_service(FILE *fp, service *temp_service)
3315 {
3316 fprintf(fp, "define service {\n");
3317 fprintf(fp, "\thost_name\t%s\n", temp_service->host_name);
3318 fprintf(fp, "\tservice_description\t%s\n", temp_service->description);
3319 if(temp_service->display_name != temp_service->description)
3320 fprintf(fp, "\tdisplay_name\t%s\n", temp_service->display_name);
3321 if(temp_service->parents) {
3322 fprintf(fp, "\tparents\t");
3323 /* same-host, single-parent? */
3324 if(!temp_service->parents->next && temp_service->parents->service_ptr->host_ptr == temp_service->host_ptr)
3325 fprintf(fp, "%s\n", temp_service->parents->service_ptr->description);
3326 else {
3327 servicesmember *sm;
3328 for(sm = temp_service->parents; sm; sm = sm->next) {
3329 fprintf(fp, "%s,%s%c", sm->host_name, sm->service_description, sm->next ? ',' : '\n');
3330 }
3331 }
3332 }
3333 if(temp_service->check_period)
3334 fprintf(fp, "\tcheck_period\t%s\n", temp_service->check_period);
3335 if(temp_service->check_command)
3336 fprintf(fp, "\tcheck_command\t%s\n", temp_service->check_command);
3337 if(temp_service->event_handler)
3338 fprintf(fp, "\tevent_handler\t%s\n", temp_service->event_handler);
3339 fcache_contactlist(fp, "\tcontacts\t", temp_service->contacts);
3340 fcache_contactgrouplist(fp, "\tcontact_groups\t", temp_service->contact_groups);
3341 if(temp_service->notification_period)
3342 fprintf(fp, "\tnotification_period\t%s\n", temp_service->notification_period);
3343 fprintf(fp, "\tinitial_state\t");
3344 if(temp_service->initial_state == STATE_WARNING)
3345 fprintf(fp, "w\n");
3346 else if(temp_service->initial_state == STATE_UNKNOWN)
3347 fprintf(fp, "u\n");
3348 else if(temp_service->initial_state == STATE_CRITICAL)
3349 fprintf(fp, "c\n");
3350 else
3351 fprintf(fp, "o\n");
3352 fprintf(fp, "\timportance\t%u\n", temp_service->hourly_value);
3353 fprintf(fp, "\tcheck_interval\t%f\n", temp_service->check_interval);
3354 fprintf(fp, "\tretry_interval\t%f\n", temp_service->retry_interval);
3355 fprintf(fp, "\tmax_check_attempts\t%d\n", temp_service->max_attempts);
3356 fprintf(fp, "\tis_volatile\t%d\n", temp_service->is_volatile);
3357 fprintf(fp, "\tparallelize_check\t%d\n", temp_service->parallelize);
3358 fprintf(fp, "\tactive_checks_enabled\t%d\n", temp_service->checks_enabled);
3359 fprintf(fp, "\tpassive_checks_enabled\t%d\n", temp_service->accept_passive_checks);
3360 fprintf(fp, "\tobsess\t%d\n", temp_service->obsess);
3361 fprintf(fp, "\tevent_handler_enabled\t%d\n", temp_service->event_handler_enabled);
3362 fprintf(fp, "\tlow_flap_threshold\t%f\n", temp_service->low_flap_threshold);
3363 fprintf(fp, "\thigh_flap_threshold\t%f\n", temp_service->high_flap_threshold);
3364 fprintf(fp, "\tflap_detection_enabled\t%d\n", temp_service->flap_detection_enabled);
3365 fprintf(fp, "\tflap_detection_options\t%s\n", opts2str(temp_service->flap_detection_options, service_flag_map, 'o'));
3366 fprintf(fp, "\tfreshness_threshold\t%d\n", temp_service->freshness_threshold);
3367 fprintf(fp, "\tcheck_freshness\t%d\n", temp_service->check_freshness);
3368 fprintf(fp, "\tnotification_options\t%s\n", opts2str(temp_service->notification_options, service_flag_map, 'r'));
3369 fprintf(fp, "\tnotifications_enabled\t%d\n", temp_service->notifications_enabled);
3370 fprintf(fp, "\tnotification_interval\t%f\n", temp_service->notification_interval);
3371 fprintf(fp, "\tfirst_notification_delay\t%f\n", temp_service->first_notification_delay);
3372 fprintf(fp, "\tstalking_options\t%s\n", opts2str(temp_service->stalking_options, service_flag_map, 'o'));
3373 fprintf(fp, "\tprocess_perf_data\t%d\n", temp_service->process_performance_data);
3374 if(temp_service->icon_image)
3375 fprintf(fp, "\ticon_image\t%s\n", temp_service->icon_image);
3376 if(temp_service->icon_image_alt)
3377 fprintf(fp, "\ticon_image_alt\t%s\n", temp_service->icon_image_alt);
3378 if(temp_service->notes)
3379 fprintf(fp, "\tnotes\t%s\n", temp_service->notes);
3380 if(temp_service->notes_url)
3381 fprintf(fp, "\tnotes_url\t%s\n", temp_service->notes_url);
3382 if(temp_service->action_url)
3383 fprintf(fp, "\taction_url\t%s\n", temp_service->action_url);
3384 fprintf(fp, "\tretain_status_information\t%d\n", temp_service->retain_status_information);
3385 fprintf(fp, "\tretain_nonstatus_information\t%d\n", temp_service->retain_nonstatus_information);
3386
3387 /* custom variables */
3388 fcache_customvars(fp, temp_service->custom_variables);
3389 fprintf(fp, "\t}\n\n");
3390 }
3391
fcache_servicedependency(FILE * fp,servicedependency * temp_servicedependency)3392 void fcache_servicedependency(FILE *fp, servicedependency *temp_servicedependency)
3393 {
3394 fprintf(fp, "define servicedependency {\n");
3395 fprintf(fp, "\thost_name\t%s\n", temp_servicedependency->host_name);
3396 fprintf(fp, "\tservice_description\t%s\n", temp_servicedependency->service_description);
3397 fprintf(fp, "\tdependent_host_name\t%s\n", temp_servicedependency->dependent_host_name);
3398 fprintf(fp, "\tdependent_service_description\t%s\n", temp_servicedependency->dependent_service_description);
3399 if(temp_servicedependency->dependency_period)
3400 fprintf(fp, "\tdependency_period\t%s\n", temp_servicedependency->dependency_period);
3401 fprintf(fp, "\tinherits_parent\t%d\n", temp_servicedependency->inherits_parent);
3402 fprintf(fp, "\t%s_failure_options\t%s\n",
3403 temp_servicedependency->dependency_type == NOTIFICATION_DEPENDENCY ? "notification" : "execution",
3404 opts2str(temp_servicedependency->failure_options, service_flag_map, 'o'));
3405 fprintf(fp, "\t}\n\n");
3406 }
3407
fcache_serviceescalation(FILE * fp,serviceescalation * temp_serviceescalation)3408 void fcache_serviceescalation(FILE *fp, serviceescalation *temp_serviceescalation)
3409 {
3410 fprintf(fp, "define serviceescalation {\n");
3411 fprintf(fp, "\thost_name\t%s\n", temp_serviceescalation->host_name);
3412 fprintf(fp, "\tservice_description\t%s\n", temp_serviceescalation->description);
3413 fprintf(fp, "\tfirst_notification\t%d\n", temp_serviceescalation->first_notification);
3414 fprintf(fp, "\tlast_notification\t%d\n", temp_serviceescalation->last_notification);
3415 fprintf(fp, "\tnotification_interval\t%f\n", temp_serviceescalation->notification_interval);
3416 if(temp_serviceescalation->escalation_period)
3417 fprintf(fp, "\tescalation_period\t%s\n", temp_serviceescalation->escalation_period);
3418 fprintf(fp, "\tescalation_options\t%s\n", opts2str(temp_serviceescalation->escalation_options, service_flag_map, 'r'));
3419
3420 if(temp_serviceescalation->contacts) {
3421 contactsmember *cl;
3422 fprintf(fp, "\tcontacts\t");
3423 for(cl = temp_serviceescalation->contacts; cl; cl = cl->next)
3424 fprintf(fp, "%s%c", cl->contact_ptr->name, cl->next ? ',' : '\n');
3425 }
3426 if(temp_serviceescalation->contact_groups) {
3427 contactgroupsmember *cgl;
3428 fprintf(fp, "\tcontact_groups\t");
3429 for (cgl = temp_serviceescalation->contact_groups; cgl; cgl = cgl->next)
3430 fprintf(fp, "%s%c", cgl->group_name, cgl->next ? ',' : '\n');
3431 }
3432 fprintf(fp, "\t}\n\n");
3433 }
3434
fcache_hostdependency(FILE * fp,hostdependency * temp_hostdependency)3435 void fcache_hostdependency(FILE *fp, hostdependency *temp_hostdependency)
3436 {
3437 fprintf(fp, "define hostdependency {\n");
3438 fprintf(fp, "\thost_name\t%s\n", temp_hostdependency->host_name);
3439 fprintf(fp, "\tdependent_host_name\t%s\n", temp_hostdependency->dependent_host_name);
3440 if(temp_hostdependency->dependency_period)
3441 fprintf(fp, "\tdependency_period\t%s\n", temp_hostdependency->dependency_period);
3442 fprintf(fp, "\tinherits_parent\t%d\n", temp_hostdependency->inherits_parent);
3443 fprintf(fp, "\t%s_failure_options\t%s\n",
3444 temp_hostdependency->dependency_type == NOTIFICATION_DEPENDENCY ? "notification" : "execution",
3445 opts2str(temp_hostdependency->failure_options, host_flag_map, 'o'));
3446 fprintf(fp, "\t}\n\n");
3447 }
3448
fcache_hostescalation(FILE * fp,hostescalation * temp_hostescalation)3449 void fcache_hostescalation(FILE *fp, hostescalation *temp_hostescalation)
3450 {
3451 fprintf(fp, "define hostescalation {\n");
3452 fprintf(fp, "\thost_name\t%s\n", temp_hostescalation->host_name);
3453 fprintf(fp, "\tfirst_notification\t%d\n", temp_hostescalation->first_notification);
3454 fprintf(fp, "\tlast_notification\t%d\n", temp_hostescalation->last_notification);
3455 fprintf(fp, "\tnotification_interval\t%f\n", temp_hostescalation->notification_interval);
3456 if(temp_hostescalation->escalation_period)
3457 fprintf(fp, "\tescalation_period\t%s\n", temp_hostescalation->escalation_period);
3458 fprintf(fp, "\tescalation_options\t%s\n", opts2str(temp_hostescalation->escalation_options, host_flag_map, 'r'));
3459
3460 fcache_contactlist(fp, "\tcontacts\t", temp_hostescalation->contacts);
3461 fcache_contactgrouplist(fp, "\tcontact_groups\t", temp_hostescalation->contact_groups);
3462 fprintf(fp, "\t}\n\n");
3463 }
3464
3465 /* writes cached object definitions for use by web interface */
fcache_objects(char * cache_file)3466 int fcache_objects(char *cache_file) {
3467 FILE *fp = NULL;
3468 time_t current_time = 0L;
3469 unsigned int i;
3470
3471 /* some people won't want to cache their objects */
3472 if(!cache_file || !strcmp(cache_file, "/dev/null"))
3473 return OK;
3474
3475 time(¤t_time);
3476
3477 /* open the cache file for writing */
3478 fp = fopen(cache_file, "w");
3479 if(fp == NULL) {
3480 logit(NSLOG_CONFIG_WARNING, TRUE, "Warning: Could not open object cache file '%s' for writing!\n", cache_file);
3481 return ERROR;
3482 }
3483
3484 /* write header to cache file */
3485 fprintf(fp, "########################################\n");
3486 fprintf(fp, "# NAGIOS OBJECT CACHE FILE\n");
3487 fprintf(fp, "#\n");
3488 fprintf(fp, "# THIS FILE IS AUTOMATICALLY GENERATED\n");
3489 fprintf(fp, "# BY NAGIOS. DO NOT MODIFY THIS FILE!\n");
3490 fprintf(fp, "#\n");
3491 fprintf(fp, "# Created: %s", ctime(¤t_time));
3492 fprintf(fp, "########################################\n\n");
3493
3494
3495 /* cache timeperiods */
3496 for(i = 0; i < num_objects.timeperiods; i++)
3497 fcache_timeperiod(fp, timeperiod_ary[i]);
3498
3499 /* cache commands */
3500 for(i = 0; i < num_objects.commands; i++)
3501 fcache_command(fp, command_ary[i]);
3502
3503 /* cache contactgroups */
3504 for(i = 0; i < num_objects.contactgroups; i++)
3505 fcache_contactgroup(fp, contactgroup_ary[i]);
3506
3507 /* cache hostgroups */
3508 for(i = 0; i < num_objects.hostgroups; i++)
3509 fcache_hostgroup(fp, hostgroup_ary[i]);
3510
3511 /* cache servicegroups */
3512 for(i = 0; i < num_objects.servicegroups; i++)
3513 fcache_servicegroup(fp, servicegroup_ary[i]);
3514
3515 /* cache contacts */
3516 for(i = 0; i < num_objects.contacts; i++)
3517 fcache_contact(fp, contact_ary[i]);
3518
3519 /* cache hosts */
3520 for(i = 0; i < num_objects.hosts; i++)
3521 fcache_host(fp, host_ary[i]);
3522
3523 /* cache services */
3524 for(i = 0; i < num_objects.services; i++)
3525 fcache_service(fp, service_ary[i]);
3526
3527 /* cache service dependencies */
3528 for(i = 0; i < num_objects.servicedependencies; i++)
3529 fcache_servicedependency(fp, servicedependency_ary[i]);
3530
3531 /* cache service escalations */
3532 for(i = 0; i < num_objects.serviceescalations; i++)
3533 fcache_serviceescalation(fp, serviceescalation_ary[i]);
3534
3535 /* cache host dependencies */
3536 for(i = 0; i < num_objects.hostdependencies; i++)
3537 fcache_hostdependency(fp, hostdependency_ary[i]);
3538
3539 /* cache host escalations */
3540 for(i = 0; i < num_objects.hostescalations; i++)
3541 fcache_hostescalation(fp, hostescalation_ary[i]);
3542
3543 fclose(fp);
3544
3545 return OK;
3546 }
3547 #endif
3548