1 /*----------------------------------------------------------------------------*/
2 /* Xymon overview webpage generator tool.                                     */
3 /*                                                                            */
4 /* This file holds code to load the page-structure from the hosts.cfg file.   */
5 /*                                                                            */
6 /* Copyright (C) 2002-2011 Henrik Storner <henrik@storner.dk>                 */
7 /*                                                                            */
8 /* This program is released under the GNU General Public License (GPL),       */
9 /* version 2. See the file "COPYING" for details.                             */
10 /*                                                                            */
11 /*----------------------------------------------------------------------------*/
12 
13 static char rcsid[] = "$Id: loadlayout.c 7105 2012-07-23 11:47:20Z storner $";
14 
15 #include <limits.h>
16 #include <stdio.h>
17 #include <string.h>
18 #include <stdlib.h>
19 #include <ctype.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <dirent.h>
23 #include <unistd.h>
24 #include <fcntl.h>
25 
26 #include "xymongen.h"
27 #include "util.h"
28 #include "loadlayout.h"
29 
30 #define MAX_TARGETPAGES_PER_HOST 10
31 
32 time_t	snapshot = 0;				/* Set if we are doing a snapshot */
33 
34 char	*null_text = "";
35 
36 /* List definition to search for page records */
37 typedef struct xymonpagelist_t {
38 	struct xymongen_page_t *pageentry;
39 	struct xymonpagelist_t *next;
40 } xymonpagelist_t;
41 
42 static xymonpagelist_t *pagelisthead = NULL;
43 int	pagecount = 0;
44 int	hostcount = 0;
45 
46 char    *wapcolumns = NULL;                     /* Default columns included in WAP cards */
47 char    *nopropyellowdefault = NULL;
48 char    *nopropreddefault = NULL;
49 char    *noproppurpledefault = NULL;
50 char    *nopropackdefault = NULL;
51 
addtopagelist(xymongen_page_t * page)52 void addtopagelist(xymongen_page_t *page)
53 {
54 	xymonpagelist_t *newitem;
55 
56 	newitem = (xymonpagelist_t *) calloc(1, sizeof(xymonpagelist_t));
57 	newitem->pageentry = page;
58 	newitem->next = pagelisthead;
59 	pagelisthead = newitem;
60 }
61 
build_noprop(char * defset,char * specset)62 char *build_noprop(char *defset, char *specset)
63 {
64 	static char result[MAX_LINE_LEN];
65 	char *set;
66 	char *item;
67 	char ibuf[MAX_LINE_LEN];
68 	char op;
69 	char *p;
70 
71 	/* It's guaranteed that specset is non-NULL. defset may be NULL */
72 	if ((*specset != '+') && (*specset != '-')) {
73 		/* Old-style - specset is the full set of tests */
74 		sprintf(result, ",%s,", specset);
75 		return result;
76 	}
77 
78 	set = strdup(specset);
79 	strcpy(result, ((defset != NULL) ? defset : ""));
80 	item = strtok(set, ",");
81 
82 	while (item) {
83 		if ((*item == '-') || (*item == '+')) {
84 			op = *item;
85 			sprintf(ibuf, ",%s,", item+1);
86 		}
87 		else {
88 			op = '+';
89 			sprintf(ibuf, ",%s,", item);
90 		}
91 
92 		p = strstr(result, ibuf);
93 		if (p && (op == '-')) {
94 			/* Remove this item */
95 			memmove(p, (p+strlen(item)), strlen(p));
96 		}
97 		else if ((p == NULL) && (op == '+')) {
98 			/* Add this item (it's not already included) */
99 			if (strlen(result) == 0) {
100 				sprintf(result, ",%s,", item+1);
101 			}
102 			else {
103 				strcat(result, item+1);
104 				strcat(result, ",");
105 			}
106 		}
107 
108 		item = strtok(NULL, ",");
109 	}
110 
111 	xfree(set);
112 	return result;	/* This may be an empty string */
113 }
114 
init_page(char * name,char * title,int vertical)115 xymongen_page_t *init_page(char *name, char *title, int vertical)
116 {
117 	xymongen_page_t *newpage = (xymongen_page_t *) calloc(1, sizeof(xymongen_page_t));
118 
119 	pagecount++;
120 	dbgprintf("init_page(%s, %s)\n", textornull(name), textornull(title));
121 
122 	if (name) {
123 		newpage->name = strdup(name);
124 	}
125 	else name = null_text;
126 
127 	if (title) {
128 		newpage->title = strdup(title);
129 	}else
130 		title = null_text;
131 
132 	newpage->color = -1;
133 	newpage->oldage = 1;
134 	newpage->vertical = vertical;
135 	newpage->pretitle = NULL;
136 	newpage->groups = NULL;
137 	newpage->hosts = NULL;
138 	newpage->parent = NULL;
139 	newpage->subpages = NULL;
140 	newpage->next = NULL;
141 
142 	return newpage;
143 }
144 
init_group(char * title,char * onlycols,char * exceptcols,int sorthosts)145 group_t *init_group(char *title, char *onlycols, char *exceptcols, int sorthosts)
146 {
147 	group_t *newgroup = (group_t *) calloc(1, sizeof(group_t));
148 
149 	dbgprintf("init_group(%s, %s)\n", textornull(title), textornull(onlycols));
150 
151 	if (title) {
152 		newgroup->title = strdup(title);
153 	}
154 	else title = null_text;
155 
156 	if (onlycols) {
157 		newgroup->onlycols = (char *) malloc(strlen(onlycols)+3); /* Add a '|' at start and end */
158 		sprintf(newgroup->onlycols, "|%s|", onlycols);
159 	}
160 	else newgroup->onlycols = NULL;
161 	if (exceptcols) {
162 		newgroup->exceptcols = (char *) malloc(strlen(exceptcols)+3); /* Add a '|' at start and end */
163 		sprintf(newgroup->exceptcols, "|%s|", exceptcols);
164 	}
165 	else newgroup->exceptcols = NULL;
166 	newgroup->pretitle = NULL;
167 	newgroup->hosts = NULL;
168 	newgroup->sorthosts = sorthosts;
169 	newgroup->next = NULL;
170 	return newgroup;
171 }
172 
init_host(char * hostname,int issummary,char * displayname,char * clientalias,char * comment,char * description,int ip1,int ip2,int ip3,int ip4,int dialup,double warnpct,int warnstops,char * reporttime,char * alerts,int crittime,char * waps,char * nopropyellowtests,char * nopropredtests,char * noproppurpletests,char * nopropacktests)173 host_t *init_host(char *hostname, int issummary,
174 		  char *displayname, char *clientalias,
175 		  char *comment, char *description,
176 		  int ip1, int ip2, int ip3, int ip4,
177 		  int dialup, double warnpct, int warnstops, char *reporttime,
178 		  char *alerts, int crittime, char *waps,
179 		  char *nopropyellowtests, char *nopropredtests, char *noproppurpletests, char *nopropacktests)
180 {
181 	host_t 		*newhost = (host_t *) calloc(1, sizeof(host_t));
182 	hostlist_t	*oldlist;
183 
184 	hostcount++;
185 	dbgprintf("init_host(%s)\n", textornull(hostname));
186 
187 	newhost->hostname = newhost->displayname = strdup(hostname);
188 	if (displayname) newhost->displayname = strdup(displayname);
189 	newhost->clientalias = (clientalias ? strdup(clientalias) : NULL);
190 	newhost->comment = (comment ? strdup(comment) : NULL);
191 	newhost->description = (description ? strdup(description) : NULL);
192 	sprintf(newhost->ip, "%d.%d.%d.%d", ip1, ip2, ip3, ip4);
193 	newhost->pretitle = NULL;
194 	newhost->entries = NULL;
195 	newhost->color = -1;
196 	newhost->oldage = 1;
197 	newhost->dialup = dialup;
198 	newhost->reportwarnlevel = warnpct;
199 	newhost->reportwarnstops = warnstops;
200 	newhost->reporttime = (reporttime ? strdup(reporttime) : NULL);
201 	if (alerts && crittime) {
202 		newhost->alerts = strdup(alerts);
203 	}
204 	else {
205 		newhost->alerts = NULL;
206 	}
207 	newhost->anywaps = 0;
208 	newhost->wapcolor = -1;
209 
210 	/* Wap set is :
211 	 * - Specific WML: tag
212 	 * - NK: tag
213 	 * - --wap=COLUMN cmdline option
214 	 * - NULL
215 	 */
216 	if (waps || alerts) {
217 		newhost->waps = strdup(waps ? waps : alerts);
218 	}
219 	else {
220 		newhost->waps = wapcolumns;
221 	}
222 
223 	if (nopropyellowtests) {
224 		char *p;
225 		p = skipword(nopropyellowtests); if (*p) *p = '\0'; else p = NULL;
226 		newhost->nopropyellowtests = strdup(build_noprop(nopropyellowdefault, nopropyellowtests));
227 		if (p) *p = ' ';
228 	}
229 	else {
230 		newhost->nopropyellowtests = nopropyellowdefault;
231 	}
232 	if (nopropredtests) {
233 		char *p;
234 		p = skipword(nopropredtests); if (*p) *p = '\0'; else p = NULL;
235 		newhost->nopropredtests = strdup(build_noprop(nopropreddefault, nopropredtests));
236 		if (p) *p = ' ';
237 	}
238 	else {
239 		newhost->nopropredtests = nopropreddefault;
240 	}
241 	if (noproppurpletests) {
242 		char *p;
243 		p = skipword(noproppurpletests); if (*p) *p = '\0'; else p = NULL;
244 		newhost->noproppurpletests = strdup(build_noprop(noproppurpledefault, noproppurpletests));
245 		if (p) *p = ' ';
246 	}
247 	else {
248 		newhost->noproppurpletests = noproppurpledefault;
249 	}
250 	if (nopropacktests) {
251 		char *p;
252 		p = skipword(nopropacktests); if (*p) *p = '\0'; else p = NULL;
253 		newhost->nopropacktests = strdup(build_noprop(nopropackdefault, nopropacktests));
254 		if (p) *p = ' ';
255 	}
256 	else {
257 		newhost->nopropacktests = nopropackdefault;
258 	}
259 
260 	newhost->parent = NULL;
261 	newhost->nonongreen = 0;
262 	newhost->next = NULL;
263 
264 	/* Summary hosts don't go into the host list */
265 	if (issummary) return newhost;
266 
267 	/*
268 	 * Add this host to the hostlist_t list of known hosts.
269 	 * HOWEVER: It might be a duplicate! In that case, we need
270 	 * to figure out which host record we want to use.
271 	 */
272 	oldlist = find_hostlist(hostname);
273 	if (oldlist == NULL) {
274 		hostlist_t *newlist;
275 
276 		newlist = (hostlist_t *) calloc(1, sizeof(hostlist_t));
277 		newlist->hostentry = newhost;
278 		newlist->clones = NULL;
279 		add_to_hostlist(newlist);
280 	}
281 	else {
282 		hostlist_t *clone = (hostlist_t *) calloc(1, sizeof(hostlist_t));
283 
284 		dbgprintf("Duplicate host definition for host '%s'\n", hostname);
285 
286 		clone->hostentry = newhost;
287 		clone->clones = oldlist->clones;
288 		oldlist->clones = clone;
289 	}
290 
291 	return newhost;
292 }
293 
294 
295 
getnamelink(char * l,char ** name,char ** link)296 void getnamelink(char *l, char **name, char **link)
297 {
298 	/* "page NAME title-or-link" splitup */
299 	char *p;
300 
301 	dbgprintf("getnamelink(%s, ...)\n", textornull(l));
302 
303 	*name = null_text;
304 	*link = null_text;
305 
306 	/* Skip page/subpage keyword, and whitespace after that */
307 	p = skipwhitespace(skipword(l));
308 
309 	*name = p; p = skipword(p);
310 	if (*p) {
311 		*p = '\0'; /* Null-terminate pagename */
312 		p++;
313 		*link = skipwhitespace(p);
314 	}
315 }
316 
317 
getparentnamelink(char * l,xymongen_page_t * toppage,xymongen_page_t ** parent,char ** name,char ** link)318 void getparentnamelink(char *l, xymongen_page_t *toppage, xymongen_page_t **parent, char **name, char **link)
319 {
320 	/* "subparent NAME PARENTNAME title-or-link" splitup */
321 	char *p;
322 	char *parentname;
323 	xymonpagelist_t *walk;
324 
325 	dbgprintf("getnamelink(%s, ...)\n", textornull(l));
326 
327 	*name = null_text;
328 	*link = null_text;
329 
330 	/* Skip page/subpage keyword, and whitespace after that */
331 	parentname = p = skipwhitespace(skipword(l));
332 	p = skipword(p);
333 	if (*p) {
334 		*p = '\0'; /* Null-terminate pagename */
335 		p++;
336 		*name = p = skipwhitespace(p);
337 	 	p = skipword(p);
338 		if (*p) {
339 			*p = '\0'; /* Null-terminate parentname */
340 			p++;
341 			*link = skipwhitespace(p);
342 		}
343 	}
344 
345 	for (walk = pagelisthead; (walk && (strcmp(walk->pageentry->name, parentname) != 0)); walk = walk->next) ;
346 	if (walk) {
347 		*parent = walk->pageentry;
348 	}
349 	else {
350 		errprintf("Cannot find parent page '%s'\n", parentname);
351 		*parent = NULL;
352 	}
353 }
354 
355 
getgrouptitle(char * l,char * pageset,char ** title,char ** onlycols,char ** exceptcols)356 void getgrouptitle(char *l, char *pageset, char **title, char **onlycols, char **exceptcols)
357 {
358 	char grouponlytag[100], groupexcepttag[100], grouptag[100];
359 
360 	*title = null_text;
361 	*onlycols = NULL;
362 	*exceptcols = NULL;
363 
364 	sprintf(grouponlytag, "%sgroup-only", pageset);
365 	sprintf(groupexcepttag, "%sgroup-except", pageset);
366 	sprintf(grouptag, "%sgroup", pageset);
367 
368 	dbgprintf("getgrouptitle(%s, ...)\n", textornull(l));
369 
370 	if (strncmp(l, grouponlytag, strlen(grouponlytag)) == 0) {
371 		char *p;
372 
373 		*onlycols = skipwhitespace(skipword(l));
374 
375 		p = skipword(*onlycols);
376 		if (*p) {
377 			*p = '\0'; p++;
378 			*title = skipwhitespace(p);
379 		}
380 	}
381 	else if (strncmp(l, groupexcepttag, strlen(groupexcepttag)) == 0) {
382 		char *p;
383 
384 		*exceptcols = skipwhitespace(skipword(l));
385 
386 		p = skipword(*exceptcols);
387 		if (*p) {
388 			*p = '\0'; p++;
389 			*title = skipwhitespace(p);
390 		}
391 	}
392 	else if (strncmp(l, grouptag, strlen(grouptag)) == 0) {
393 		*title = skipwhitespace(skipword(l));
394 	}
395 }
396 
init_summary(char * name,char * receiver,char * url)397 summary_t *init_summary(char *name, char *receiver, char *url)
398 {
399 	summary_t *newsum;
400 
401 	dbgprintf("init_summary(%s, %s, %s)\n", textornull(name), textornull(receiver), textornull(url));
402 
403 	/* Sanity check */
404 	if ((name == NULL) || (receiver == NULL) || (url == NULL))
405 		return NULL;
406 
407 	newsum = (summary_t *) calloc(1, sizeof(summary_t));
408 	newsum->name = strdup(name);
409 	newsum->receiver = strdup(receiver);
410 	newsum->url = strdup(url);
411 	newsum->next = NULL;
412 
413 	return newsum;
414 }
415 
416 
load_layout(char * pgset)417 xymongen_page_t *load_layout(char *pgset)
418 {
419 	char	pagetag[100], subpagetag[100], subparenttag[100],
420 		vpagetag[100], vsubpagetag[100], vsubparenttag[100],
421 		grouptag[100], summarytag[100], titletag[100], hosttag[100];
422 	char 	*name, *link, *onlycols, *exceptcols;
423 	char 	hostname[MAX_LINE_LEN];
424 	xymongen_page_t 	*toppage, *curpage, *cursubpage, *cursubparent;
425 	group_t *curgroup;
426 	host_t	*curhost;
427 	char	*curtitle;
428 	int	ip1, ip2, ip3, ip4;
429 	char	*p;
430 	int	fqdn = get_fqdn();
431 	char	*cfgdata, *inbol, *ineol, insavchar = '\0';
432 
433 	if (loadhostsfromxymond) {
434 		if (load_hostnames("@", NULL, fqdn) != 0) {
435 			errprintf("Cannot load host configuration from xymond\n");
436 			return NULL;
437 		}
438 	}
439 	else {
440 		if (load_hostnames(xgetenv("HOSTSCFG"), "dispinclude", fqdn) != 0) {
441 			errprintf("Cannot load host configuration from %s\n", xgetenv("HOSTSCFG"));
442 			return NULL;
443 		}
444 	}
445 
446 	if (first_host() == NULL) {
447 		errprintf("Empty configuration from %s\n", (loadhostsfromxymond ? "xymond" : xgetenv("HOSTSCFG")));
448 		return NULL;
449 	}
450 
451 	dbgprintf("load_layout(pgset=%s)\n", textornull(pgset));
452 
453 	/*
454 	 * load_hostnames() picks up the hostname definitions, but not the page
455 	 * layout. So we will scan the file again, this time doing the layout.
456 	 */
457 
458 	if (pgset == NULL) pgset = "";
459 	sprintf(pagetag, "%spage", pgset);
460 	sprintf(subpagetag, "%ssubpage", pgset);
461 	sprintf(subparenttag, "%ssubparent", pgset);
462 	sprintf(vpagetag, "v%spage", pgset);
463 	sprintf(vsubpagetag, "v%ssubpage", pgset);
464 	sprintf(vsubparenttag, "v%ssubparent", pgset);
465 	sprintf(grouptag, "%sgroup", pgset);
466 	sprintf(summarytag, "%ssummary", pgset);
467 	sprintf(titletag, "%stitle", pgset);
468 	sprintf(hosttag, "%s:", pgset); for (p=hosttag; (*p); p++) *p = toupper((int)*p);
469 
470 	toppage = init_page("", "", 0);
471 	addtopagelist(toppage);
472 	curpage = NULL;
473 	cursubpage = NULL;
474 	curgroup = NULL;
475 	curhost = NULL;
476 	cursubparent = NULL;
477 	curtitle = NULL;
478 
479 	inbol = cfgdata = hostscfg_content();
480 	while (inbol && *inbol) {
481 		inbol += strspn(inbol, " \t");
482 		ineol = strchr(inbol, '\n');
483 		if (ineol) {
484 			while ((ineol > inbol) && (isspace(*ineol) || (*ineol == '\n'))) ineol--;
485 			if (*ineol != '\n') ineol++;
486 
487 			insavchar = *ineol;
488 			*ineol = '\0';
489 		}
490 
491 		dbgprintf("load_layout: -- got line '%s'\n", inbol);
492 
493 		if ((strncmp(inbol, pagetag, strlen(pagetag)) == 0) || (strncmp(inbol, vpagetag, strlen(vpagetag)) == 0)) {
494 			getnamelink(inbol, &name, &link);
495 			if (curpage == NULL) {
496 				/* First page - hook it on toppage as a subpage from there */
497 				curpage = toppage->subpages = init_page(name, link, (strncmp(inbol, vpagetag, strlen(vpagetag)) == 0));
498 			}
499 			else {
500 				curpage = curpage->next = init_page(name, link, (strncmp(inbol, vpagetag, strlen(vpagetag)) == 0));
501 			}
502 
503 			curpage->parent = toppage;
504 			if (curtitle) {
505 				curpage->pretitle = curtitle;
506 				curtitle = NULL;
507 			}
508 			cursubpage = NULL;
509 			cursubparent = NULL;
510 			curgroup = NULL;
511 			curhost = NULL;
512 			addtopagelist(curpage);
513 		}
514 		else if ( (strncmp(inbol, subpagetag, strlen(subpagetag)) == 0) || (strncmp(inbol, vsubpagetag, strlen(vsubpagetag)) == 0) ) {
515 			if (curpage == NULL) {
516 				errprintf("'subpage' ignored, no preceding 'page' tag : %s\n", inbol);
517 				goto nextline;
518 			}
519 
520 			getnamelink(inbol, &name, &link);
521 			if (cursubpage == NULL) {
522 				cursubpage = curpage->subpages = init_page(name, link, (strncmp(inbol, vsubpagetag, strlen(vsubpagetag)) == 0));
523 			}
524 			else {
525 				cursubpage = cursubpage->next = init_page(name, link, (strncmp(inbol, vsubpagetag, strlen(vsubpagetag)) == 0));
526 			}
527 			cursubpage->parent = curpage;
528 			if (curtitle) {
529 				cursubpage->pretitle = curtitle;
530 				curtitle = NULL;
531 			}
532 			cursubparent = NULL;
533 			curgroup = NULL;
534 			curhost = NULL;
535 			addtopagelist(cursubpage);
536 		}
537 		else if ( (strncmp(inbol, subparenttag, strlen(subparenttag)) == 0) || (strncmp(inbol, vsubparenttag, strlen(vsubparenttag)) == 0) ) {
538 			xymongen_page_t *parentpage, *walk;
539 
540 			getparentnamelink(inbol, toppage, &parentpage, &name, &link);
541 			if (parentpage == NULL) {
542 				errprintf("'subparent' ignored, unknown parent page: %s\n", inbol);
543 				goto nextline;
544 			}
545 
546 			cursubparent = init_page(name, link, (strncmp(inbol, vsubparenttag, strlen(vsubparenttag)) == 0));
547 			if (parentpage->subpages == NULL) {
548 				parentpage->subpages = cursubparent;
549 			}
550 			else {
551 				for (walk = parentpage->subpages; (walk->next); (walk = walk->next)) ;
552 				walk->next = cursubparent;
553 			}
554 			if (curtitle) {
555 				cursubparent->pretitle = curtitle;
556 				curtitle = NULL;
557 			}
558 			cursubparent->parent = parentpage;
559 			curgroup = NULL;
560 			curhost = NULL;
561 			addtopagelist(cursubparent);
562 		}
563 		else if (strncmp(inbol, grouptag, strlen(grouptag)) == 0) {
564 			int sorthosts = (strstr(inbol, "group-sorted") != NULL);
565 
566 			getgrouptitle(inbol, pgset, &link, &onlycols, &exceptcols);
567 			if (curgroup == NULL) {
568 				curgroup = init_group(link, onlycols, exceptcols, sorthosts);
569 				if (cursubparent != NULL) {
570 					cursubparent->groups = curgroup;
571 				}
572 				else if (cursubpage != NULL) {
573 					/* We're in a subpage */
574 					cursubpage->groups = curgroup;
575 				}
576 				else if (curpage != NULL) {
577 					/* We're on a main page */
578 					curpage->groups = curgroup;
579 				}
580 				else {
581 					/* We're on the top page */
582 					toppage->groups = curgroup;
583 				}
584 			}
585 			else {
586 				curgroup->next = init_group(link, onlycols, exceptcols, sorthosts);
587 				curgroup = curgroup->next;
588 			}
589 			if (curtitle) { curgroup->pretitle = curtitle; curtitle = NULL; }
590 			curhost = NULL;
591 		}
592 		else if (sscanf(inbol, "%3d.%3d.%3d.%3d %s", &ip1, &ip2, &ip3, &ip4, hostname) == 5) {
593 			void *xymonhost = NULL;
594 			int dialup, nonongreen, crittime = 1;
595 			double warnpct = reportwarnlevel;
596 			int warnstops = reportwarnstops;
597 			char *displayname, *clientalias, *comment, *description;
598 			char *alertlist, *onwaplist, *reporttime;
599 			char *nopropyellowlist, *nopropredlist, *noproppurplelist, *nopropacklist;
600 			char *targetpagelist[MAX_TARGETPAGES_PER_HOST];
601 			int targetpagecount;
602 			char *hval;
603 
604 			/* Check for ".default." hosts - they are ignored. */
605 			if (*hostname == '.') goto nextline;
606 
607 			if (!fqdn) {
608 				/* Strip any domain from the hostname */
609 				char *p = strchr(hostname, '.');
610 				if (p) *p = '\0';
611 			}
612 
613 			/* Get the info */
614 			xymonhost = hostinfo(hostname);
615 			if (xymonhost == NULL) {
616 				errprintf("Confused - hostname '%s' cannot be found. Ignored\n", hostname);
617 				goto nextline;
618 			}
619 
620 			/* Check for no-display hosts - they are ignored. */
621 			/* But only when we're building the default pageset */
622 			if ((strlen(pgset) == 0) && (xmh_item(xymonhost, XMH_FLAG_NODISP) != NULL)) goto nextline;
623 
624 			for (targetpagecount=0; (targetpagecount < MAX_TARGETPAGES_PER_HOST); targetpagecount++)
625 				targetpagelist[targetpagecount] = NULL;
626 			targetpagecount = 0;
627 
628 			dialup = (xmh_item(xymonhost, XMH_FLAG_DIALUP) != NULL);
629 			nonongreen = (xmh_item(xymonhost, XMH_FLAG_NONONGREEN) != NULL);
630 
631 			alertlist = xmh_item(xymonhost, XMH_NK);
632 			hval = xmh_item(xymonhost, XMH_NKTIME); if (hval) crittime = within_sla(xmh_item(xymonhost, XMH_HOLIDAYS), hval, 0);
633 
634 			onwaplist = xmh_item(xymonhost, XMH_WML);
635 			nopropyellowlist = xmh_item(xymonhost, XMH_NOPROPYELLOW);
636 			if (nopropyellowlist == NULL) nopropyellowlist = xmh_item(xymonhost, XMH_NOPROP);
637 			nopropredlist = xmh_item(xymonhost, XMH_NOPROPRED);
638 			noproppurplelist = xmh_item(xymonhost, XMH_NOPROPPURPLE);
639 			nopropacklist = xmh_item(xymonhost, XMH_NOPROPACK);
640 			displayname = xmh_item(xymonhost, XMH_DISPLAYNAME);
641 			comment = xmh_item(xymonhost, XMH_COMMENT);
642 			description = xmh_item(xymonhost, XMH_DESCRIPTION);
643 			hval = xmh_item(xymonhost, XMH_WARNPCT); if (hval) warnpct = atof(hval);
644 			hval = xmh_item(xymonhost, XMH_WARNSTOPS); if (hval) warnstops = atof(hval);
645 			reporttime = xmh_item(xymonhost, XMH_REPORTTIME);
646 
647 			clientalias = xmh_item(xymonhost, XMH_CLIENTALIAS);
648 			if (xymonhost && (strcmp(xmh_item(xymonhost, XMH_HOSTNAME), clientalias) == 0)) clientalias = NULL;
649 
650 			if (xymonhost && (strlen(pgset) > 0)) {
651 				/* Walk the clone-list and pick up the target pages for this host */
652 				void *cwalk = xymonhost;
653 				do {
654 					hval = xmh_item_walk(cwalk);
655 					while (hval) {
656 						if (strncasecmp(hval, hosttag, strlen(hosttag)) == 0)
657 							targetpagelist[targetpagecount++] = strdup(hval+strlen(hosttag));
658 						hval = xmh_item_walk(NULL);
659 					}
660 
661 					cwalk = next_host(cwalk, 1);
662 				} while (cwalk &&
663 					 (strcmp(xmh_item(cwalk, XMH_HOSTNAME), xmh_item(xymonhost, XMH_HOSTNAME)) == 0) &&
664 					 (targetpagecount < MAX_TARGETPAGES_PER_HOST) );
665 
666 				/*
667 				 * HACK: Check if the pageset tag is present at all in the host
668 				 * entry. If it isn't, then drop this incarnation of the host.
669 				 *
670 				 * Without this, the following hosts.cfg file will have the
671 				 * www.hswn.dk host listed twice on the alternate pageset:
672 				 *
673 				 * adminpage nyc NYC
674 				 *
675 				 * 127.0.0.1   localhost      # bbd http://localhost/ CLIENT:osiris
676 				 * 172.16.10.2 www.xymon.com  # http://www.xymon.com/ ADMIN:nyc ssh noinfo
677 				 *
678 				 * page superdome Superdome
679 				 * 172.16.10.2 www.xymon.com # noconn
680 				 *
681 				 */
682 				if (strstr(inbol, hosttag) == NULL) targetpagecount = 0;
683 			}
684 
685 			if (strlen(pgset) == 0) {
686 				/*
687 				 * Default pageset generated. Put the host into
688 				 * whatever group or page is current.
689 				 */
690 				if (curhost == NULL) {
691 					curhost = init_host(hostname, 0, displayname, clientalias,
692 							    comment, description,
693 							    ip1, ip2, ip3, ip4, dialup,
694 							    warnpct, warnstops, reporttime,
695 							    alertlist, crittime, onwaplist,
696 							    nopropyellowlist, nopropredlist, noproppurplelist, nopropacklist);
697 					if (curgroup != NULL) {
698 						curgroup->hosts = curhost;
699 					}
700 					else if (cursubparent != NULL) {
701 						cursubparent->hosts = curhost;
702 					}
703 					else if (cursubpage != NULL) {
704 						cursubpage->hosts = curhost;
705 					}
706 					else if (curpage != NULL) {
707 						curpage->hosts = curhost;
708 					}
709 					else {
710 						toppage->hosts = curhost;
711 					}
712 				}
713 				else {
714 					curhost = curhost->next = init_host(hostname, 0, displayname, clientalias,
715 									    comment, description,
716 									    ip1, ip2, ip3, ip4, dialup,
717 									    warnpct, warnstops, reporttime,
718 									    alertlist, crittime, onwaplist,
719 									    nopropyellowlist,nopropredlist,
720 									    noproppurplelist, nopropacklist);
721 				}
722 				curhost->parent = (cursubparent ? cursubparent : (cursubpage ? cursubpage : curpage));
723 				if (curtitle) { curhost->pretitle = curtitle; curtitle = NULL; }
724 				curhost->nonongreen = nonongreen;
725 			}
726 			else if (targetpagecount) {
727 
728 				int pgnum;
729 
730 				for (pgnum=0; (pgnum < targetpagecount); pgnum++) {
731 					char *targetpagename = targetpagelist[pgnum];
732 
733 					char savechar;
734 					int wantedgroup = 0;
735 					xymonpagelist_t *targetpage = NULL;
736 
737 					/* Put the host into the page specified by the PGSET: tag */
738 					p = strchr(targetpagename, ',');
739 					if (p) {
740 						savechar = *p;
741 						*p = '\0';
742 						wantedgroup = atoi(p+1);
743 					}
744 					else {
745 						savechar = '\0';
746 						p = targetpagename + strlen(targetpagename);
747 					}
748 
749 					/* Find the page */
750 					if (strcmp(targetpagename, "*") == 0) {
751 						*targetpagename = '\0';
752 					}
753 					for (targetpage = pagelisthead; (targetpage && (strcmp(targetpagename, targetpage->pageentry->name) != 0)); targetpage = targetpage->next) ;
754 
755 					*p = savechar;
756 					if (targetpage == NULL) {
757 						errprintf("Warning: Cannot find any target page named '%s' in set '%s' - dropping host '%s'\n",
758 							targetpagename, pgset, hostname);
759 					}
760 					else {
761 						host_t *newhost = init_host(hostname, 0, displayname, clientalias,
762 									    comment, description,
763 									    ip1, ip2, ip3, ip4, dialup,
764 									    warnpct, warnstops, reporttime,
765 									    alertlist, crittime, onwaplist,
766 									    nopropyellowlist,nopropredlist,
767 									    noproppurplelist, nopropacklist);
768 
769 						if (wantedgroup > 0) {
770 							group_t *gwalk;
771 							host_t  *hwalk;
772 							int i;
773 
774 							for (gwalk = targetpage->pageentry->groups, i=1; (gwalk && (i < wantedgroup)); i++,gwalk=gwalk->next) ;
775 							if (gwalk) {
776 								if (gwalk->hosts == NULL)
777 									gwalk->hosts = newhost;
778 								else {
779 									for (hwalk = gwalk->hosts; (hwalk->next); hwalk = hwalk->next) ;
780 									hwalk->next = newhost;
781 								}
782 							}
783 							else {
784 								errprintf("Warning: Cannot find group %d for host %s - dropping host\n",
785 									wantedgroup, hostname);
786 							}
787 						}
788 						else {
789 							/* Just put in on the page's hostlist */
790 							host_t *walk;
791 
792 							if (targetpage->pageentry->hosts == NULL)
793 								targetpage->pageentry->hosts = newhost;
794 							else {
795 								for (walk = targetpage->pageentry->hosts; (walk->next); walk = walk->next) ;
796 								walk->next = newhost;
797 							}
798 						}
799 
800 						newhost->parent = targetpage->pageentry;
801 						if (curtitle) newhost->pretitle = curtitle;
802 					}
803 
804 					curtitle = NULL;
805 				}
806 			}
807 		}
808 		else if (strncmp(inbol, summarytag, strlen(summarytag)) == 0) {
809 			/* summary row.column      IP-ADDRESS-OF-PARENT    http://xymon.com/ */
810 			char sumname[MAX_LINE_LEN];
811 			char receiver[MAX_LINE_LEN];
812 			char url[MAX_LINE_LEN];
813 			summary_t *newsum;
814 
815 			if (sscanf(inbol, "summary %s %s %s", sumname, receiver, url) == 3) {
816 				newsum = init_summary(sumname, receiver, url);
817 				newsum->next = sumhead;
818 				sumhead = newsum;
819 			}
820 		}
821 		else if (strncmp(inbol, titletag, strlen(titletag)) == 0) {
822 			/* Save the title for the next entry */
823 			curtitle = strdup(skipwhitespace(skipword(inbol)));
824 		}
825 
826 nextline:
827 		if (ineol) {
828 			*ineol = insavchar;
829 			if (*ineol != '\n') ineol = strchr(ineol, '\n');
830 
831 			inbol = (ineol ? ineol+1 : NULL);
832 		}
833 		else
834 			inbol = NULL;
835 	}
836 
837 	xfree(cfgdata);
838 	return toppage;
839 }
840 
841