int load_hostnames(char *hostsfn, char *extrainclude, int fqdn) { /* Return value: 0 for load OK, 1 for "No files changed since last load", -1 for error (file not found) */ int prepresult; int ip1, ip2, ip3, ip4, groupid, pageidx; char hostname[4096], *dgname; pagelist_t *curtoppage, *curpage, *pgtail; namelist_t *nametail = NULL; void * htree; char *cfgdata, *inbol, *ineol, insavchar = '\0'; load_hostinfo(NULL); if (*hostsfn == '!') prepresult = prepare_fromfile(hostsfn+1, extrainclude); else if (extrainclude) prepresult = prepare_fromfile(hostsfn, extrainclude); else if ((*hostsfn == '@') || (strcmp(hostsfn, xgetenv("HOSTSCFG")) == 0)) { prepresult = prepare_fromnet(); if (prepresult == -1) { errprintf("Failed to load from xymond, reverting to file-load\n"); prepresult = prepare_fromfile(xgetenv("HOSTSCFG"), extrainclude); } } else prepresult = prepare_fromfile(hostsfn, extrainclude); /* Did we get the data ? */ if (prepresult == -1) { errprintf("Cannot load host data\n"); return -1; } /* Any modifications at all ? */ if (prepresult == 1) { dbgprintf("No files modified, skipping reload of %s\n", hostsfn); return 1; } MEMDEFINE(hostname); MEMDEFINE(l); configloaded = 1; initialize_hostlist(); curpage = curtoppage = pgtail = pghead; pageidx = groupid = 0; dgname = NULL; htree = xtreeNew(strcasecmp); inbol = cfgdata = hostscfg_content(); while (inbol && *inbol) { inbol += strspn(inbol, " \t"); ineol = strchr(inbol, '\n'); if (ineol) { while ((ineol > inbol) && (isspace(*ineol) || (*ineol == '\n'))) ineol--; if (*ineol != '\n') ineol++; insavchar = *ineol; *ineol = '\0'; } if (strncmp(inbol, "page", 4) == 0) { pagelist_t *newp; char *name, *title; pageidx = groupid = 0; if (dgname) xfree(dgname); dgname = NULL; if (get_page_name_title(inbol, "page", &name, &title) == 0) { newp = (pagelist_t *)malloc(sizeof(pagelist_t)); newp->pagepath = strdup(name); newp->pagetitle = (title ? strdup(title) : NULL); newp->next = NULL; pgtail->next = newp; pgtail = newp; curpage = curtoppage = newp; } } else if (strncmp(inbol, "subpage", 7) == 0) { pagelist_t *newp; char *name, *title; pageidx = groupid = 0; if (dgname) xfree(dgname); dgname = NULL; if (get_page_name_title(inbol, "subpage", &name, &title) == 0) { newp = (pagelist_t *)malloc(sizeof(pagelist_t)); newp->pagepath = malloc(strlen(curtoppage->pagepath) + strlen(name) + 2); sprintf(newp->pagepath, "%s/%s", curtoppage->pagepath, name); newp->pagetitle = malloc(strlen(curtoppage->pagetitle) + strlen(title) + 2); sprintf(newp->pagetitle, "%s/%s", curtoppage->pagetitle, title); newp->next = NULL; pgtail->next = newp; pgtail = newp; curpage = newp; } } else if (strncmp(inbol, "subparent", 9) == 0) { pagelist_t *newp, *parent; char *pname, *name, *title; pageidx = groupid = 0; if (dgname) xfree(dgname); dgname = NULL; parent = NULL; if (get_page_name_title(inbol, "subparent", &pname, &title) == 0) { for (parent = pghead; (parent && !pagematch(parent, pname)); parent = parent->next); } if (parent && (get_page_name_title(title, "", &name, &title) == 0)) { newp = (pagelist_t *)malloc(sizeof(pagelist_t)); newp->pagepath = malloc(strlen(parent->pagepath) + strlen(name) + 2); sprintf(newp->pagepath, "%s/%s", parent->pagepath, name); newp->pagetitle = malloc(strlen(parent->pagetitle) + strlen(title) + 2); sprintf(newp->pagetitle, "%s/%s", parent->pagetitle, title); newp->next = NULL; pgtail->next = newp; pgtail = newp; curpage = newp; } } else if (strncmp(inbol, "group", 5) == 0) { char *tok; groupid++; if (dgname) xfree(dgname); dgname = NULL; tok = strtok(inbol, " \t"); if ((strcmp(tok, "group-only") == 0) || (strcmp(tok, "group-except") == 0)) { tok = strtok(NULL, " \t"); } if (tok) tok = strtok(NULL, "\r\n"); if (tok) { char *inp; /* Strip HTML tags from the string */ dgname = (char *)malloc(strlen(tok) + 1); *dgname = '\0'; inp = tok; while (*inp) { char *tagstart, *tagend; tagstart = strchr(inp, '<'); if (tagstart) { tagend = strchr(tagstart, '>'); *tagstart = '\0'; if (*inp) strcat(dgname, inp); if (tagend) { inp = tagend+1; } else { /* Unmatched '<', keep all of the string */ *tagstart = '<'; strcat(dgname, tagstart); inp += strlen(inp); } } else { strcat(dgname, inp); inp += strlen(inp); } } } } else if (sscanf(inbol, "%d.%d.%d.%d %s", &ip1, &ip2, &ip3, &ip4, hostname) == 5) { char *startoftags, *tag, *delim; int elemidx, elemsize; char groupidstr[10]; xtreePos_t handle; namelist_t *newitem, *iwalk, *iprev; if ( (ip1 < 0) || (ip1 > 255) || (ip2 < 0) || (ip2 > 255) || (ip3 < 0) || (ip3 > 255) || (ip4 < 0) || (ip4 > 255)) { errprintf("Invalid IPv4-address for host %s (nibble outside 0-255 range): %d.%d.%d.%d\n", hostname, ip1, ip2, ip3, ip4); goto nextline; } newitem = calloc(1, sizeof(namelist_t)); /* Hostname beginning with '@' are "no-display" hosts. But we still want them. */ if (*hostname == '@') memmove(hostname, hostname+1, strlen(hostname)); if (!fqdn) { /* Strip any domain from the hostname */ char *p = strchr(hostname, '.'); if (p) *p = '\0'; } sprintf(newitem->ip, "%d.%d.%d.%d", ip1, ip2, ip3, ip4); sprintf(groupidstr, "%d", groupid); newitem->groupid = strdup(groupidstr); newitem->dgname = (dgname ? strdup(dgname) : strdup("NONE")); newitem->pageindex = pageidx++; newitem->hostname = strdup(hostname); if (ip1 || ip2 || ip3 || ip4) newitem->preference = 1; else newitem->preference = 0; newitem->logname = strdup(newitem->hostname); { char *p = newitem->logname; while ((p = strchr(p, '.')) != NULL) { *p = '_'; } } newitem->page = curpage; newitem->defaulthost = defaulthost; startoftags = strchr(inbol, '#'); if (startoftags == NULL) startoftags = ""; else startoftags++; startoftags += strspn(startoftags, " \t\r\n"); newitem->allelems = strdup(startoftags); elemsize = 5; newitem->elems = (char **)malloc((elemsize+1)*sizeof(char *)); tag = newitem->allelems; elemidx = 0; while (tag && *tag) { if (elemidx == elemsize) { elemsize += 5; newitem->elems = (char **)realloc(newitem->elems, (elemsize+1)*sizeof(char *)); } newitem->elems[elemidx] = tag; /* Skip until we hit a whitespace or a quote */ tag += strcspn(tag, " \t\r\n\""); if (*tag == '"') { delim = tag; /* Hit a quote - skip until the next matching quote */ tag = strchr(tag+1, '"'); if (tag != NULL) { /* Found end-quote, NULL the item here and move on */ *tag = '\0'; tag++; } /* Now move quoted data one byte down (including the NUL) to kill quotechar */ memmove(delim, delim+1, strlen(delim)); } else if (*tag) { /* Normal end of item, NULL it and move on */ *tag = '\0'; tag++; } else { /* End of line - no more to do. */ tag = NULL; } /* * If we find a "noconn", drop preference value to 0. * If we find a "prefer", up reference value to 2. */ if ((newitem->preference == 1) && (strcmp(newitem->elems[elemidx], "noconn") == 0)) newitem->preference = 0; else if (strcmp(newitem->elems[elemidx], "prefer") == 0) newitem->preference = 2; /* Skip whitespace until start of next tag */ if (tag) tag += strspn(tag, " \t\r\n"); elemidx++; } newitem->elems[elemidx] = NULL; /* See if this host is defined before */ handle = xtreeFind(htree, newitem->hostname); if (strcasecmp(newitem->hostname, ".default.") == 0) { /* The pseudo DEFAULT host */ newitem->next = NULL; defaulthost = newitem; } else if (handle == xtreeEnd(htree)) { /* New item, so add to end of list */ newitem->next = NULL; if (namehead == NULL) namehead = nametail = newitem; else { nametail->next = newitem; nametail = newitem; } xtreeAdd(htree, newitem->hostname, newitem); } else { /* Find the existing record - compare the record pointer instead of the name */ namelist_t *existingrec = (namelist_t *)xtreeData(htree, handle); for (iwalk = namehead, iprev = NULL; ((iwalk != existingrec) && iwalk); iprev = iwalk, iwalk = iwalk->next) ; if (newitem->preference <= iwalk->preference) { /* Add after the existing (more preferred) entry */ newitem->next = iwalk->next; iwalk->next = newitem; } else { /* New item has higher preference, so add before the iwalk item (i.e. after iprev) */ if (iprev == NULL) { newitem->next = namehead; namehead = newitem; } else { newitem->next = iprev->next; iprev->next = newitem; } } } newitem->clientname = xmh_find_item(newitem, XMH_CLIENTALIAS); if (newitem->clientname == NULL) newitem->clientname = newitem->hostname; newitem->downtime = xmh_find_item(newitem, XMH_DOWNTIME); } nextline: if (ineol) { *ineol = insavchar; if (*ineol != '\n') ineol = strchr(ineol, '\n'); inbol = (ineol ? ineol+1 : NULL); } else inbol = NULL; } xfree(cfgdata); if (dgname) xfree(dgname); xtreeDestroy(htree); MEMUNDEFINE(hostname); MEMUNDEFINE(l); build_hosttree(); return 0; }
int load_hostnames(char *bbhostsfn, char *extrainclude, int fqdn) { /* Return value: 0 for load OK, 1 for "No files changed since last load", -1 for error (file not found) */ static void *bbhfiles = NULL; FILE *bbhosts; int ip1, ip2, ip3, ip4, groupid, pageidx; char hostname[4096]; strbuffer_t *inbuf; pagelist_t *curtoppage, *curpage, *pgtail; namelist_t *nametail = NULL; RbtHandle htree; /* First check if there were no modifications at all */ if (bbhfiles) { if (!stackfmodified(bbhfiles)){ dbgprintf("No files modified, skipping reload of %s\n", bbhostsfn); return 1; } else { stackfclist(&bbhfiles); bbhfiles = NULL; } } MEMDEFINE(hostname); MEMDEFINE(l); configloaded = 1; initialize_hostlist(); curpage = curtoppage = pgtail = pghead; pageidx = groupid = 0; bbhosts = stackfopen(bbhostsfn, "r", &bbhfiles); if (bbhosts == NULL) return -1; inbuf = newstrbuffer(0); htree = rbtNew(name_compare); while (stackfgets(inbuf, extrainclude)) { sanitize_input(inbuf, 0, 0); if (strncmp(STRBUF(inbuf), "page", 4) == 0) { pagelist_t *newp; char *name, *title; pageidx = groupid = 0; if (get_page_name_title(STRBUF(inbuf), "page", &name, &title) == 0) { newp = (pagelist_t *)malloc(sizeof(pagelist_t)); newp->pagepath = strdup(name); newp->pagetitle = (title ? strdup(title) : NULL); newp->next = NULL; pgtail->next = newp; pgtail = newp; curpage = curtoppage = newp; } } else if (strncmp(STRBUF(inbuf), "subpage", 7) == 0) { pagelist_t *newp; char *name, *title; pageidx = groupid = 0; if (get_page_name_title(STRBUF(inbuf), "subpage", &name, &title) == 0) { newp = (pagelist_t *)malloc(sizeof(pagelist_t)); newp->pagepath = malloc(strlen(curtoppage->pagepath) + strlen(name) + 2); sprintf(newp->pagepath, "%s/%s", curtoppage->pagepath, name); newp->pagetitle = malloc(strlen(curtoppage->pagetitle) + strlen(title) + 2); sprintf(newp->pagetitle, "%s/%s", curtoppage->pagetitle, title); newp->next = NULL; pgtail->next = newp; pgtail = newp; curpage = newp; } } else if (strncmp(STRBUF(inbuf), "subparent", 9) == 0) { pagelist_t *newp, *parent; char *pname, *name, *title; pageidx = groupid = 0; parent = NULL; if (get_page_name_title(STRBUF(inbuf), "subparent", &pname, &title) == 0) { for (parent = pghead; (parent && !pagematch(parent, pname)); parent = parent->next); } if (parent && (get_page_name_title(title, "", &name, &title) == 0)) { newp = (pagelist_t *)malloc(sizeof(pagelist_t)); newp->pagepath = malloc(strlen(parent->pagepath) + strlen(name) + 2); sprintf(newp->pagepath, "%s/%s", parent->pagepath, name); newp->pagetitle = malloc(strlen(parent->pagetitle) + strlen(title) + 2); sprintf(newp->pagetitle, "%s/%s", parent->pagetitle, title); newp->next = NULL; pgtail->next = newp; pgtail = newp; curpage = newp; } } else if (strncmp(STRBUF(inbuf), "group", 5) == 0) { groupid++; } else if (sscanf(STRBUF(inbuf), "%d.%d.%d.%d %s", &ip1, &ip2, &ip3, &ip4, hostname) == 5) { char *startoftags, *tag, *delim; int elemidx, elemsize; char clientname[4096]; char downtime[4096]; char groupidstr[10]; RbtIterator handle; namelist_t *newitem = calloc(1, sizeof(namelist_t)); namelist_t *iwalk, *iprev; MEMDEFINE(clientname); MEMDEFINE(downtime); /* Hostname beginning with '@' are "no-display" hosts. But we still want them. */ if (*hostname == '@') memmove(hostname, hostname+1, strlen(hostname)); if (!fqdn) { /* Strip any domain from the hostname */ char *p = strchr(hostname, '.'); if (p) *p = '\0'; } sprintf(newitem->ip, "%d.%d.%d.%d", ip1, ip2, ip3, ip4); sprintf(groupidstr, "%d", groupid); newitem->groupid = strdup(groupidstr); newitem->pageindex = pageidx++; newitem->bbhostname = strdup(hostname); if (ip1 || ip2 || ip3 || ip4) newitem->preference = 1; else newitem->preference = 0; newitem->logname = strdup(newitem->bbhostname); { char *p = newitem->logname; while ((p = strchr(p, '.')) != NULL) { *p = '_'; } } newitem->page = curpage; newitem->defaulthost = defaulthost; clientname[0] = downtime[0] = '\0'; startoftags = strchr(STRBUF(inbuf), '#'); if (startoftags == NULL) startoftags = ""; else startoftags++; startoftags += strspn(startoftags, " \t\r\n"); newitem->allelems = strdup(startoftags); elemsize = 5; newitem->elems = (char **)malloc((elemsize+1)*sizeof(char *)); tag = newitem->allelems; elemidx = 0; while (tag && *tag) { if (elemidx == elemsize) { elemsize += 5; newitem->elems = (char **)realloc(newitem->elems, (elemsize+1)*sizeof(char *)); } newitem->elems[elemidx] = tag; /* Skip until we hit a whitespace or a quote */ tag += strcspn(tag, " \t\r\n\""); if (*tag == '"') { delim = tag; /* Hit a quote - skip until the next matching quote */ tag = strchr(tag+1, '"'); if (tag != NULL) { /* Found end-quote, NULL the item here and move on */ *tag = '\0'; tag++; } /* Now move quoted data one byte down (including the NUL) to kill quotechar */ memmove(delim, delim+1, strlen(delim)); } else if (*tag) { /* Normal end of item, NULL it and move on */ *tag = '\0'; tag++; } else { /* End of line - no more to do. */ tag = NULL; } /* * If we find a "noconn", drop preference value to 0. * If we find a "prefer", up reference value to 2. */ if ((newitem->preference == 1) && (strcmp(newitem->elems[elemidx], "noconn") == 0)) newitem->preference = 0; else if (strcmp(newitem->elems[elemidx], "prefer") == 0) newitem->preference = 2; /* Skip whitespace until start of next tag */ if (tag) tag += strspn(tag, " \t\r\n"); elemidx++; } newitem->elems[elemidx] = NULL; /* See if this host is defined before */ handle = rbtFind(htree, newitem->bbhostname); if (strcasecmp(newitem->bbhostname, ".default.") == 0) { /* The pseudo DEFAULT host */ newitem->next = NULL; defaulthost = newitem; } else if (handle == rbtEnd(htree)) { /* New item, so add to end of list */ newitem->next = NULL; if (namehead == NULL) namehead = nametail = newitem; else { nametail->next = newitem; nametail = newitem; } rbtInsert(htree, newitem->bbhostname, newitem); } else { /* Find the existing record - compare the record pointer instead of the name */ namelist_t *existingrec = (namelist_t *)gettreeitem(htree, handle); for (iwalk = namehead, iprev = NULL; ((iwalk != existingrec) && iwalk); iprev = iwalk, iwalk = iwalk->next) ; if (newitem->preference <= iwalk->preference) { /* Add after the existing (more preferred) entry */ newitem->next = iwalk->next; iwalk->next = newitem; } else { /* New item has higher preference, so add before the iwalk item (i.e. after iprev) */ if (iprev == NULL) { newitem->next = namehead; namehead = newitem; } else { newitem->next = iprev->next; iprev->next = newitem; } } } newitem->clientname = bbh_find_item(newitem, BBH_CLIENTALIAS); if (newitem->clientname == NULL) newitem->clientname = newitem->bbhostname; newitem->downtime = bbh_find_item(newitem, BBH_DOWNTIME); MEMUNDEFINE(clientname); MEMUNDEFINE(downtime); } } stackfclose(bbhosts); freestrbuffer(inbuf); rbtDelete(htree); MEMUNDEFINE(hostname); MEMUNDEFINE(l); build_hosttree(); return 0; }