static holiday_t *findholiday(char *key, int dayinyear) { xtreePos_t handle; holidayset_t *hset; holiday_t *p; if (key && *key) { handle = xtreeFind(holidays, key); if (handle == xtreeEnd(holidays)) { key = NULL; handle = xtreeFind(holidays, ""); } } else { key = NULL; handle = xtreeFind(holidays, ""); } if (handle != xtreeEnd(holidays)) hset = (holidayset_t *)xtreeData(holidays, handle); else return NULL; p = hset->head; while (p) { if (dayinyear == p->yday) { return p; } p = p->next; } return NULL; }
hostinfo_t *register_host(char *hostname, enum locator_servicetype_t servicetype, char *servername) { xtreePos_t handle; hostinfo_t *itm = NULL; handle = xtreeFind(hitree[servicetype], hostname); if (handle == xtreeEnd(hitree[servicetype])) { itm = (hostinfo_t *)calloc(1, sizeof(hostinfo_t)); itm->hostname = strdup(hostname); xtreeAdd(hitree[servicetype], itm->hostname, itm); } else { itm = xtreeData(hitree[servicetype], handle); } /* If we dont know this server, then we must register it. If we do, just update the host record */ handle = xtreeFind(sitree[servicetype], servername); if (handle == xtreeEnd(sitree[servicetype])) { dbgprintf("Registering default server '%s'\n", servername); itm->server = register_server(servername, servicetype, 1, 1, NULL); } else { serverinfo_t *newserver = xtreeData(sitree[servicetype], handle); if (itm->server && (itm->server != newserver)) { errprintf("Warning: Host %s:%s moved from %s to %s\n", hostname, servicetype_names[servicetype], itm->server->servername, newserver->servername); } itm->server = newserver; } return itm; }
void save_state(void) { char *tmpdir; char *fn; FILE *fd; int tidx; tmpdir = xgetenv("XYMONTMP"); if (!tmpdir) tmpdir = "/tmp"; fn = (char *)malloc(strlen(tmpdir) + 100); sprintf(fn, "%s/locator.servers.chk", tmpdir); fd = fopen(fn, "w"); if (fd == NULL) { errprintf("Cannot save state to %s: %s\n", fn, strerror(errno)); return; } for (tidx = 0; (tidx < ST_MAX); tidx++) { const char *tname = servicetype_names[tidx]; xtreePos_t handle; serverinfo_t *itm; for (handle = xtreeFirst(sitree[tidx]); (handle != xtreeEnd(sitree[tidx])); handle = xtreeNext(sitree[tidx], handle)) { itm = xtreeData(sitree[tidx], handle); fprintf(fd, "%s|%s|%d|%d|%d|%s\n", tname, itm->servername, itm->serverconfweight, itm->serveractualweight, ((itm->sticky == LOC_STICKY) ? 1 : 0), (itm->serverextras ? itm->serverextras : "")); } } fclose(fd); sprintf(fn, "%s/locator.hosts.chk", tmpdir); fd = fopen(fn, "w"); if (fd == NULL) { errprintf("Cannot save state to %s: %s\n", fn, strerror(errno)); return; } for (tidx = 0; (tidx < ST_MAX); tidx++) { const char *tname = servicetype_names[tidx]; xtreePos_t handle; hostinfo_t *itm; for (handle = xtreeFirst(hitree[tidx]); (handle != xtreeEnd(hitree[tidx])); handle = xtreeNext(hitree[tidx], handle)) { itm = xtreeData(hitree[tidx], handle); if (itm->server) { fprintf(fd, "%s|%s|%s\n", tname, itm->hostname, itm->server->servername); } } } fclose(fd); }
void save_session_cookies(void) { FILE *fd = NULL; char cookiefn[PATH_MAX]; xtreePos_t h; hcookie_t *itm; sprintf(cookiefn, "%s/etc/cookies.session", xgetenv("XYMONHOME")); fd = fopen(cookiefn, "w"); if (fd == NULL) return; for (h=xtreeFirst(cookietree); (h != xtreeEnd(cookietree)); h = xtreeNext(cookietree, h)) { char *urlhost, *ckpath, *cknam; itm = (hcookie_t *)xtreeData(cookietree, h); urlhost = strtok(itm->key, "\t"); cknam = strtok(NULL, "\t"); ckpath = strtok(NULL, "\t"); fprintf(fd, "%s\tFALSE\t%s\tFALSE\t0\t%s\t%s\n", urlhost, ckpath, cknam, itm->val); } fclose(fd); }
void print_oneprio(FILE *output, void * statetree, void * hoptree, void * rbcolumns, int prio) { xtreePos_t hhandle; static int firsthostever = 1; int firsthostthisprio = 1; char *curhost = ""; /* Then output each host and their column status */ for (hhandle = xtreeFirst(statetree); (hhandle != xtreeEnd(statetree)); hhandle = xtreeNext(statetree, hhandle)) { hstatus_t *itm; itm = (hstatus_t *)xtreeData(statetree, hhandle); if (itm->config->priority != prio) continue; if (strcmp(curhost, itm->hostname) == 0) continue; /* New host */ curhost = itm->hostname; print_hoststatus(output, itm, statetree, rbcolumns, prio, firsthostthisprio, firsthostever); xtreeAdd(hoptree, itm->hostname, itm); firsthostthisprio = 0; } /* If we did output any hosts, make some room for the next priority */ if (!firsthostthisprio) fprintf(output, "<TR><TD> </TD></TR>\n"); }
static void reset_holidays(void) { static int firsttime = 1; xtreePos_t handle; holidayset_t *hset; holiday_t *walk, *zombie; if (!firsttime) { for (handle = xtreeFirst(holidays); (handle != xtreeEnd(holidays)); handle = xtreeNext(holidays, handle)) { hset = (holidayset_t *)xtreeData(holidays, handle); xfree(hset->key); walk = hset->head; while (walk) { zombie = walk; walk = walk->next; xfree(zombie->desc); xfree(zombie); } } xtreeDestroy(holidays); } holidays_like_weekday = -1; firsttime = 0; holidays = xtreeNew(strcasecmp); }
void update_session_cookies(char *hostname, char *urlhost, char *headers) { char *ckhdr, *onecookie; if (!headers) return; ckhdr = headers; do { ckhdr = strstr(ckhdr, "\nSet-Cookie:"); if (ckhdr) { /* Set-Cookie: JSESSIONID=rKy8HZbLgT5W9N8; path=/ */ char *eoln, *cknam, *ckval, *ckpath; cknam = ckval = ckpath = NULL; onecookie = strchr(ckhdr, ':') + 1; onecookie += strspn(onecookie, " \t"); eoln = strchr(onecookie, '\n'); if (eoln) *eoln = '\0'; ckhdr = (eoln ? eoln : NULL); onecookie = strdup(onecookie); if (eoln) *eoln = '\n'; cknam = strtok(onecookie, "="); if (cknam) ckval = strtok(NULL, ";"); if (ckval) { char *tok, *key; xtreePos_t h; hcookie_t *itm; do { tok = strtok(NULL, ";\r"); if (tok) { tok += strspn(tok, " "); if (strncmp(tok, "path=", 5) == 0) { ckpath = tok+5; } } } while (tok); if (ckpath == NULL) ckpath = "/"; key = (char *)malloc(strlen(urlhost) + strlen(cknam) + strlen(ckpath) + 3); sprintf(key, "%s\t%s\t%s", urlhost, cknam, ckpath); h = xtreeFind(cookietree, key); if (h == xtreeEnd(cookietree)) { itm = (hcookie_t *)malloc(sizeof(hcookie_t)); itm->key = key; itm->val = strdup(ckval); xtreeAdd(cookietree, itm->key, itm); } else { itm = (hcookie_t *)xtreeData(cookietree, h); xfree(itm->val); itm->val = strdup(ckval); xfree(key); } } xfree(onecookie); } } while (ckhdr); }
static void locator_updatecache(enum locator_servicetype_t svc, char *key, char *resp) { xtreePos_t handle; cacheitm_t *newitm; if (!havecache[svc]) return; handle = xtreeFind(locatorcache[svc], key); if (handle == xtreeEnd(locatorcache[svc])) { newitm = (cacheitm_t *)calloc(1, sizeof(cacheitm_t)); newitm->key = strdup(key); newitm->resp = strdup(resp); if (xtreeAdd(locatorcache[svc], newitm->key, newitm) != XTREE_STATUS_OK) { xfree(newitm->key); xfree(newitm->resp); xfree(newitm); } } else { newitm = (cacheitm_t *)xtreeData(locatorcache[svc], handle); if (newitm->resp) xfree(newitm->resp); newitm->resp = strdup(resp); newitm->tstamp = getcurrenttime(NULL); } }
serverinfo_t *register_server(char *servername, enum locator_servicetype_t servicetype, int weight, enum locator_sticky_t sticky, char *extras) { xtreePos_t handle; serverinfo_t *itm = NULL; handle = xtreeFind(sitree[servicetype], servername); if (handle == xtreeEnd(sitree[servicetype])) { itm = (serverinfo_t *)calloc(1, sizeof(serverinfo_t)); itm->servername = strdup(servername); xtreeAdd(sitree[servicetype], itm->servername, itm); } else { /* Update existing item */ itm = xtreeData(sitree[servicetype], handle); } itm->serverconfweight = itm->serveractualweight = weight; itm->serverweightleft = 0; itm->sticky = sticky; if (itm->serverextras) xfree(itm->serverextras); itm->serverextras = (extras ? strdup(extras) : NULL); if (weight < 0) recalc_current(servicetype); return itm; }
void clean_all_active(void) { xtreePos_t handle; for (handle = xtreeFirst(hostnames); handle != xtreeEnd(hostnames); handle = xtreeNext(hostnames, handle)) { alertanchor_t *anchor = (alertanchor_t *)xtreeData(hostnames, handle); clean_active(anchor); } }
activealerts_t *find_active(char *hostname, char *testname) { xtreePos_t handle; alertanchor_t *anchor; char *twalk; activealerts_t *awalk; handle = xtreeFind(hostnames, hostname); if (handle == xtreeEnd(hostnames)) return NULL; anchor = (alertanchor_t *)xtreeData(hostnames, handle); handle = xtreeFind(testnames, testname); if (handle == xtreeEnd(testnames)) return NULL; twalk = (char *)xtreeData(testnames, handle); for (awalk = anchor->head; (awalk && (awalk->testname != twalk)); awalk=awalk->next) ; return awalk; }
static link_t *find_link(char *key) { link_t *l = NULL; xtreePos_t handle; handle = xtreeFind(linkstree, key); if (handle != xtreeEnd(linkstree)) l = (link_t *)xtreeData(linkstree, handle); return l; }
void recalc_current(enum locator_servicetype_t stype) { /* Point our "last-used-server" pointer at the server with the most negative weight */ xtreePos_t handle, wantedserver; serverinfo_t *oneserver; int minweight = INT_MAX; wantedserver = xtreeEnd(sitree[stype]); for (handle = xtreeFirst(sitree[stype]); (handle != xtreeEnd(sitree[stype])); handle = xtreeNext(sitree[stype], handle)) { oneserver = (serverinfo_t *)xtreeData(sitree[stype], handle); if (oneserver->serveractualweight < minweight) { wantedserver = handle; minweight = oneserver->serveractualweight; } } sicurrent[stype] = wantedserver; }
void locator_flushcache(enum locator_servicetype_t svc, char *key) { xtreePos_t handle; if (!havecache[svc]) return; if (key) { handle = xtreeFind(locatorcache[svc], key); if (handle != xtreeEnd(locatorcache[svc])) { cacheitm_t *itm = (cacheitm_t *)xtreeData(locatorcache[svc], handle); itm->tstamp = 0; } } else { for (handle = xtreeFirst(locatorcache[svc]); (handle != xtreeEnd(locatorcache[svc])); handle = xtreeNext(locatorcache[svc], handle)) { cacheitm_t *itm = (cacheitm_t *)xtreeData(locatorcache[svc], handle); itm->tstamp = 0; } } }
void add_active(char *hostname, activealerts_t *rec) { xtreePos_t handle; alertanchor_t *anchor; handle = xtreeFind(hostnames, hostname); if (handle == xtreeEnd(hostnames)) return; anchor = (alertanchor_t *)xtreeData(hostnames, handle); rec->next = anchor->head; anchor->head = rec; }
char *get_clientconfig(char *hostname, char *hostclass, char *hostos) { xtreePos_t handle; char *result = NULL; if (!clientconfigs) return NULL; /* * Find the client config. Search for a HOSTNAME entry first, * then the CLIENTCLASS, then CLIENTOS. */ handle = xtreeFind(rbconfigs, hostname); if ((handle == xtreeEnd(rbconfigs)) && hostclass && *hostclass) handle = xtreeFind(rbconfigs, hostclass); if ((handle == xtreeEnd(rbconfigs)) && hostos && *hostos) handle = xtreeFind(rbconfigs, hostos); if (handle != xtreeEnd(rbconfigs)) result = (char *)xtreeData(rbconfigs, handle); return result; }
hostinfo_t *rename_host(char *oldhostname, enum locator_servicetype_t servicetype, char *newhostname) { xtreePos_t handle, newhandle; hostinfo_t *itm = NULL; handle = xtreeFind(hitree[servicetype], oldhostname); if (handle == xtreeEnd(hitree[servicetype])) return NULL; newhandle = xtreeFind(hitree[servicetype], newhostname); if (newhandle != xtreeEnd(hitree[servicetype])) { errprintf("Ignored rename of %s to %s - new name already exists\n", oldhostname, newhostname); return NULL; } itm = xtreeData(hitree[servicetype], handle); xtreeDelete(hitree[servicetype], oldhostname); xfree(itm->hostname); itm->hostname = strdup(newhostname); xtreeAdd(hitree[servicetype], itm->hostname, itm); return itm; }
activealerts_t *alistBegin(void) { alisthandle = xtreeFirst(hostnames); alistwalk = NULL; while ((alisthandle != xtreeEnd(hostnames)) && (alistwalk == NULL)) { alertanchor_t *anchor = (alertanchor_t *)xtreeData(hostnames, alisthandle); alistwalk = anchor->head; if (alistwalk == NULL) alisthandle = xtreeNext(hostnames, alisthandle); } return alistwalk; }
serverinfo_t *find_server_by_host(enum locator_servicetype_t servicetype, char *hostname) { xtreePos_t handle; hostinfo_t *hinfo; handle = xtreeFind(hitree[servicetype], hostname); if (handle == xtreeEnd(hitree[servicetype])) { return NULL; } hinfo = xtreeData(hitree[servicetype], handle); return hinfo->server; }
static char *locator_querycache(enum locator_servicetype_t svc, char *key) { xtreePos_t handle; cacheitm_t *itm; if (!havecache[svc]) return NULL; handle = xtreeFind(locatorcache[svc], key); if (handle == xtreeEnd(locatorcache[svc])) return NULL; itm = (cacheitm_t *)xtreeData(locatorcache[svc], handle); return (itm->tstamp + cachetimeout[svc]) > getcurrenttime(NULL) ? itm->resp : NULL; }
serverinfo_t *downup_server(char *servername, enum locator_servicetype_t servicetype, char action) { xtreePos_t handle; serverinfo_t *itm = NULL; handle = xtreeFind(sitree[servicetype], servername); if (handle == xtreeEnd(sitree[servicetype])) return NULL; /* Update existing item */ itm = xtreeData(sitree[servicetype], handle); switch (action) { case 'F': /* Flag the hosts that point to this server as un-assigned */ for (handle = xtreeFirst(hitree[servicetype]); (handle != xtreeEnd(hitree[servicetype])); handle = xtreeNext(hitree[servicetype], handle)) { hostinfo_t *hitm = (hostinfo_t *)xtreeData(hitree[servicetype], handle); if (hitm->server == itm) hitm->server = NULL; } /* Fall through */ case 'D': dbgprintf("Downing server '%s' type %s\n", servername, servicetype_names[servicetype]); itm->serveractualweight = 0; itm->serverweightleft = 0; if (itm->serverconfweight < 0) recalc_current(servicetype); break; case 'U': dbgprintf("Upping server '%s' type %s to weight %d\n", servername, servicetype_names[servicetype], itm->serverconfweight); itm->serveractualweight = itm->serverconfweight; /* Dont mess with serverweightleft - this may just be an "i'm alive" message */ if (itm->serverconfweight < 0) recalc_current(servicetype); break; } return itm; }
void * columnlist(void * statetree) { void * rbcolumns; xtreePos_t hhandle; rbcolumns = xtreeNew(strcasecmp); for (hhandle = xtreeFirst(statetree); (hhandle != xtreeEnd(statetree)); hhandle = xtreeNext(statetree, hhandle)) { hstatus_t *itm; itm = (hstatus_t *)xtreeData(statetree, hhandle); xtreeAdd(rbcolumns, itm->testname, NULL); } return rbcolumns; }
activealerts_t *alistNext(void) { if (!alistwalk) return NULL; alistwalk = alistwalk->next; if (alistwalk) return alistwalk; alisthandle = xtreeNext(hostnames, alisthandle); alistwalk = NULL; while ((alisthandle != xtreeEnd(hostnames)) && (alistwalk == NULL)) { alertanchor_t *anchor = (alertanchor_t *)xtreeData(hostnames, alisthandle); alistwalk = anchor->head; if (alistwalk == NULL) alisthandle = xtreeNext(hostnames, alisthandle); } return alistwalk; }
char *find_name(void * tree, char *name) { char *result; xtreePos_t handle; handle = xtreeFind(tree, name); if (handle == xtreeEnd(tree)) { result = strdup(name); if (tree == hostnames) { alertanchor_t *anchor = malloc(sizeof(alertanchor_t)); anchor->head = NULL; xtreeAdd(tree, result, anchor); } else { xtreeAdd(tree, result, result); } } else { result = (char *)xtreeKey(tree, handle); } return result; }
void print_colheaders(FILE *output, void * rbcolumns) { int colcount; xtreePos_t colhandle; colcount = 1; /* Remember the hostname column */ /* Group column headings */ fprintf(output, "<TR>"); fprintf(output, "<TD ROWSPAN=2> </TD>\n"); /* For the prio column - in both row headers+dash rows */ fprintf(output, "<TD ROWSPAN=2> </TD>\n"); /* For the host column - in both row headers+dash rows */ for (colhandle = xtreeFirst(rbcolumns); (colhandle != xtreeEnd(rbcolumns)); colhandle = xtreeNext(rbcolumns, colhandle)) { char *colname; colname = (char *)xtreeKey(rbcolumns, colhandle); colcount++; fprintf(output, " <TD ALIGN=CENTER VALIGN=BOTTOM WIDTH=45>\n"); fprintf(output, " <A HREF=\"%s\"><FONT %s><B>%s</B></FONT></A> </TD>\n", columnlink(colname), xgetenv("XYMONPAGECOLFONT"), colname); } fprintf(output, "</TR>\n"); fprintf(output, "<TR><TD COLSPAN=%d><HR WIDTH=\"100%%\"></TD></TR>\n\n", colcount); }
int do_la_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) { static char *la_params[] = { "DS:la:GAUGE:600:U:U", NULL }; static void *la_tpl = NULL; static char *clock_params[] = { "DS:la:GAUGE:600:U:U", NULL }; /* "la" is a misnomer, but to stay compatiable with existing RRD files */ static void *clock_tpl = NULL; static pcre *as400_exp = NULL; static pcre *zVM_exp = NULL; static time_t starttime = 0; char *p, *eoln = NULL; int gotusers=0, gotprocs=0, gotload=0, gotclock=0; int users=0, procs=0, load=0, clockdiff=0; time_t now = getcurrenttime(NULL); if (la_tpl == NULL) la_tpl = setup_template(la_params); if (clock_tpl == NULL) clock_tpl = setup_template(clock_params); if (starttime == 0) starttime = now; if (strstr(msg, "bb-xsnmp")) { /* * bb-xsnmp.pl script output. * * green Tue Apr 5 12:57:37 2005 up: 254.58 days, CPU Usage= 9% * * &green CPU Time in Busy Mode: 9% * &green CPU Time in Idle Mode: 91% * * &yellow CPU Usage Threshold: 90% * &red CPU Usage Threshold: 95% * * <!-- Enterprise: netapp , Version: 6.42 --> * bb-xsnmp.pl Version: 1.78 */ p = strstr(msg, "CPU Usage="); if (p) { p += strlen("CPU Usage="); gotload = 1; load = atoi(p); } goto done_parsing; } else if (strstr(msg, "z/VM") || strstr(msg, "VSE/ESA") || strstr(msg, "z/VSE") || strstr(msg, "z/OS")) { /* z/VM cpu message. Looks like this, from Rich Smrcina (client config mode): * green 5 Apr 2005 20:07:34 CPU Utilization 7% z/VM Version 4 Release 4.0, service level 0402 (32-bit) AVGPROC-007% 01 * VSE/ESA or z/VSE cpu message. * VSE/ESA 2.7.2 cr IPLed on ... * or * z/VSE 3.1.1 cr IPLed on ... * In server (centralized) config mode or for z/OS (which is centralized config only) * the operating system name is part of the message (as in the tests above). */ int ovector[30]; char w[100]; int res; if (zVM_exp == NULL) { const char *errmsg = NULL; int errofs = 0; zVM_exp = pcre_compile(".* CPU Utilization *([0-9]+)%", PCRE_CASELESS, &errmsg, &errofs, NULL); } res = pcre_exec(zVM_exp, NULL, msg, strlen(msg), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); if (res >= 0) { /* We have a match - pick up the data. */ *w = '\0'; if (res > 0) pcre_copy_substring(msg, ovector, res, 1, w, sizeof(w)); if (strlen(w)) { load = atoi(w); gotload = 1; } } goto done_parsing; } eoln = strchr(msg, '\n'); if (eoln) *eoln = '\0'; p = strstr(msg, "up: "); if (!p) p = strstr(msg, "Uptime:"); /* Netapp filerstats2bb script */ if (!p) p = strstr(msg, "uptime:"); if (p) { /* First line of cpu report, contains "up: 159 days, 1 users, 169 procs, load=21" */ p = strchr(p, ','); if (p) { gotusers = (sscanf(p, ", %d users", &users) == 1); p = strchr(p+1, ','); } if (p) { gotprocs = (sscanf(p, ", %d procs", &procs) == 1); p = strchr(p+1, ','); } /* * Load can be either * - "load=xx%" (Windows) * - "load=xx.xx" (Unix, DISPREALLOADAVG=TRUE) * - "load=xx" (Unix, DISPREALLOADAVG=FALSE) * * We want the load in percent (Windows), or LA*100 (Unix). */ p = strstr(msg, "load="); if (p) { p += 5; if (strchr(p, '%')) { gotload = 1; load = atoi(p); } else if (strchr(p, '.')) { gotload = 1; load = 100*atoi(p); /* Find the decimal part, and cut off at 2 decimals */ p = strchr(p, '.'); if (strlen(p) > 3) *(p+3) = '\0'; load += atoi(p+1); } else { gotload = 1; load = atoi(p); } } } else { /* * No "uptime" in message - could be from an AS/400. They look like this: * green March 21, 2005 12:33:24 PM EST deltacdc 108 users 45525 jobs(126 batch,0 waiting for message), load=26% */ int ovector[30]; char w[100]; int res; if (as400_exp == NULL) { const char *errmsg = NULL; int errofs = 0; as400_exp = pcre_compile(".* ([0-9]+) users ([0-9]+) jobs.* load=([0-9]+)\\%", PCRE_CASELESS, &errmsg, &errofs, NULL); } res = pcre_exec(as400_exp, NULL, msg, strlen(msg), 0, 0, ovector, (sizeof(ovector)/sizeof(int))); if (res >= 0) { /* We have a match - pick up the AS/400 data. */ *w = '\0'; if (res > 0) pcre_copy_substring(msg, ovector, res, 1, w, sizeof(w)); if (strlen(w)) { users = atoi(w); gotusers = 1; } *w = '\0'; if (res > 0) pcre_copy_substring(msg, ovector, res, 3, w, sizeof(w)); if (strlen(w)) { load = atoi(w); gotload = 1; } } } done_parsing: if (eoln) *eoln = '\n'; p = strstr(msg, "System clock is "); if (p) { if (sscanf(p, "System clock is %d seconds off", &clockdiff) == 1) gotclock = 1; } if (!gotload) { /* See if it's a report from the ciscocpu.pl script. */ p = strstr(msg, "<br>CPU 5 min average:"); if (p) { /* It reports in % cpu utilization */ p = strchr(p, ':'); load = atoi(p+1); gotload = 1; } } if (gotload) { setupfn("%s.rrd", "la"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, load); create_and_update_rrd(hostname, testname, classname, pagepaths, la_params, la_tpl); } if (gotprocs) { setupfn("%s.rrd", "procs"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, procs); create_and_update_rrd(hostname, testname, classname, pagepaths, la_params, la_tpl); } if (gotusers) { setupfn("%s.rrd", "users"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, users); create_and_update_rrd(hostname, testname, classname, pagepaths, la_params, la_tpl); } if (gotclock) { setupfn("%s.rrd", "clock"); snprintf(rrdvalues, sizeof(rrdvalues), "%d:%d", (int)tstamp, clockdiff); create_and_update_rrd(hostname, testname, classname, pagepaths, clock_params, clock_tpl); } /* * If we have run for less than 6 minutes, drop the memory updates here. * We want to be sure not to use memory statistics from the CPU report * if there is a memory add-on sending a separate memory statistics */ if ((now - starttime) < 360) return 0; if (!memhosts_init || (xtreeFind(memhosts, hostname) == xtreeEnd(memhosts))) { /* Pick up memory statistics */ int found, overflow, realuse, swapuse; long long phystotal, physavail, pagetotal, pageavail; found = overflow = realuse = swapuse = 0; phystotal = physavail = pagetotal = pageavail = 0; p = strstr(msg, "Total Physical memory:"); if (p) { phystotal = str2ll(strchr(p, ':') + 1, NULL); if (phystotal != LONG_MAX) found++; else overflow++; } if (found == 1) { p = strstr(msg, "Available Physical memory:"); if (p) { physavail = str2ll(strchr(p, ':') + 1, NULL); if (physavail != LONG_MAX) found++; else overflow++; } } if (found == 2) { p = strstr(msg, "Total PageFile size:"); if (p) { pagetotal = str2ll(strchr(p, ':') + 1, NULL); if (pagetotal != LONG_MAX) found++; else overflow++; } } if (found == 3) { p = strstr(msg, "Available PageFile size:"); if (p) { pageavail = str2ll(strchr(p, ':') + 1, NULL); if (pageavail != LONG_MAX) found++; else overflow++; } } if (found == 4) { if (!phystotal || !pagetotal) { errprintf("Host %s cpu report had 0 total physical/pagefile memory listed\n", hostname); return 0; } phystotal = phystotal / 100; pagetotal = pagetotal / 100; realuse = 100 - (physavail / phystotal); swapuse = 100 - (pageavail / pagetotal); do_memory_rrd_update(tstamp, hostname, testname, classname, pagepaths, realuse, swapuse, -1); } else if (overflow) { errprintf("Host %s cpu report overflows in memory usage calculation\n", hostname); } } return 0; }
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; }
serverinfo_t *find_server_by_type(enum locator_servicetype_t servicetype) { serverinfo_t *nextserver = NULL; xtreePos_t endmarker = xtreeEnd(sitree[servicetype]); /* * We must do weight handling here. * * Some weights (the serveractualweight attribute) have special meaning: * Negative: Only one server receives requests. We should use the * server with the lowest weight. * 0 : This server is down and cannot receive any requests. * 1 : Server is up, but should only receive requests for hosts * that have been registered as resident on this server. * >1 : Server is up and handles any request. * * When looking for a server, we do a weighted round-robin of the * servers that are available. The idea is that each server has * "serveractualweight" tokens, and we use them one by one for each * request. "serveractualweightleft" tells how many tokens are left. * When a server has been used once, we go to the next server which * has any tokens left. When all tokens have been used, we replenish * the token counts from "serveractualweight" and start over. * * sicurrent[servicetype] points to the tree-handle of the last server * that was used. */ if (sicurrent[servicetype] != endmarker) { serverinfo_t *lastserver; /* We have a last-server-used for this request */ lastserver = xtreeData(sitree[servicetype], sicurrent[servicetype]); /* * See if our the last server used handles all requests. * If it does, then sicurrent[servicetype] will ALWAYS * contain the server we want to use (it is updated * whenever servers register or weights change). */ if (lastserver->serveractualweight < 0) return lastserver; /* OK, we have now used one token from this server. */ if (lastserver->serveractualweight > 1) lastserver->serverweightleft -= 1; /* Go to the next server with any tokens left */ do { sicurrent[servicetype] = xtreeNext(sitree[servicetype], sicurrent[servicetype]); if (sicurrent[servicetype] == endmarker) { /* Start from the beginning again */ sicurrent[servicetype] = xtreeFirst(sitree[servicetype]); } nextserver = xtreeData(sitree[servicetype], sicurrent[servicetype]); } while ((nextserver->serverweightleft == 0) && (nextserver != lastserver)); if ((nextserver == lastserver) && (nextserver->serverweightleft == 0)) { /* Could not find any servers with a token left for us to use */ nextserver = NULL; } } if (nextserver == NULL) { /* Restart server RR walk */ int totalweight = 0; xtreePos_t handle, firstok; serverinfo_t *srv; firstok = endmarker; /* Walk the list of servers, calculate total weight and find the first active server */ for (handle = xtreeFirst(sitree[servicetype]); ( (handle != endmarker) && (totalweight >= 0) ); handle = xtreeNext(sitree[servicetype], handle) ) { srv = xtreeData(sitree[servicetype], handle); if (srv->serveractualweight <= 1) continue; srv->serverweightleft = (srv->serveractualweight - 1); totalweight += srv->serverweightleft; if (firstok == endmarker) firstok = handle; } sicurrent[servicetype] = firstok; nextserver = (firstok != endmarker) ? xtreeData(sitree[servicetype], firstok) : NULL; } return nextserver; }
int main(int argc, char *argv[]) { int argi; char *envarea = NULL; char **critconfig = NULL; int cccount = 0; char *hffile = "critical"; critconfig = (char **)calloc(1, sizeof(char *)); for (argi = 1; (argi < argc); argi++) { if (argnmatch(argv[argi], "--env=")) { char *p = strchr(argv[argi], '='); loadenv(p+1, envarea); } else if (argnmatch(argv[argi], "--area=")) { char *p = strchr(argv[argi], '='); envarea = strdup(p+1); } else if (strcmp(argv[argi], "--debug") == 0) { debug = 1; } else if (strcmp(argv[argi], "--tooltips") == 0) { usetooltips = 1; } else if (argnmatch(argv[argi], "--acklevel=")) { char *p = strchr(argv[argi], '='); critacklevel = atoi(p+1); } else if (argnmatch(argv[argi], "--config=")) { char *p = strchr(argv[argi], '='); critconfig[cccount] = strdup(p+1); cccount++; critconfig = (char **)realloc(critconfig, (1 + cccount)*sizeof(char *)); critconfig[cccount] = NULL; } else if (argnmatch(argv[argi], "--hffile=")) { char *p = strchr(argv[argi], '='); hffile = strdup(p+1); } } if (!critconfig[0]) { critconfig = (char **)realloc(critconfig, 2*sizeof(char *)); critconfig[0] = (char *)malloc(strlen(xgetenv("XYMONHOME")) + strlen(DEFAULT_CRITCONFIGFN) + 2); sprintf(critconfig[0], "%s/%s", xgetenv("XYMONHOME"), DEFAULT_CRITCONFIGFN); critconfig[1] = NULL; } redirect_cgilog("criticalview"); setdocurl(hostsvcurl("%s", xgetenv("INFOCOLUMN"), 1)); parse_query(); load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn()); load_all_links(); fprintf(stdout, "Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE")); use_recentgifs = 1; if (getboard(mincolor) == 0) { int i; char *oneconfig, *onename; int *partcolor = NULL, *partprio = NULL; xtreePos_t hhandle; for (i=0; (critconfig[i]); i++) { oneconfig = strchr(critconfig[i], ':'); load_critconfig(oneconfig ? oneconfig+1 : critconfig[i]); loadstatus(maxprio, maxage, mincolor, wantacked); /* Determine background color and max. priority */ if (i == 0) { partcolor = (int *)malloc(sizeof(int)); partprio = (int *)malloc(sizeof(int)); } else { partcolor = (int *)realloc(partcolor, (i+1)*sizeof(int)); partprio = (int *)realloc(partprio, (i+1)*sizeof(int)); } partcolor[i] = COL_GREEN; partprio[i] = 0; for (hhandle = xtreeFirst(rbstate[i]); (hhandle != xtreeEnd(rbstate[i])); hhandle = xtreeNext(rbstate[i], hhandle)) { hstatus_t *itm; itm = (hstatus_t *)xtreeData(rbstate[i], hhandle); if (itm->color > partcolor[i]) partcolor[i] = itm->color; if (itm->config->priority > partprio[i]) partprio[i] = itm->config->priority; } if (partcolor[i] > pagecolor) pagecolor = partcolor[i]; } for (i=0; (critconfig[i]); i++) { oneconfig = strchr(critconfig[i], ':'); if (oneconfig) { *oneconfig = '\0'; oneconfig++; onename = (char *)malloc(strlen("DIVIDERTEXT=") + strlen(critconfig[i]) + 1); sprintf(onename, "DIVIDERTEXT=%s", critconfig[i]); putenv(onename); } else { oneconfig = critconfig[i]; putenv("DIVIDERTEXT="); } generate_critpage(rbstate[i], hostsonpage[i], stdout, (i == 0) ? (critconfig[1] ? "critmulti" : hffile) : "divider", (critconfig[i+1] == NULL) ? hffile : "divider", partcolor[i], partprio[i]); } } else { fprintf(stdout, "Cannot load Xymon status\n"); } return 0; }
static void load_rrddefs(void) { char fn[PATH_MAX]; FILE *fd; strbuffer_t *inbuf = newstrbuffer(0); char *key = NULL, *p; char **defs = NULL; int defcount = 0; rrddeftree_t *newrec; rrddeftree = xtreeNew(strcasecmp); sprintf(fn, "%s/etc/rrddefinitions.cfg", xgetenv("XYMONHOME")); fd = stackfopen(fn, "r", NULL); if (fd == NULL) goto loaddone; while (stackfgets(inbuf, NULL)) { sanitize_input(inbuf, 1, 0); if (STRBUFLEN(inbuf) == 0) continue; if (*(STRBUF(inbuf)) == '[') { if (key && (defcount > 0)) { /* Save the current record */ newrec = (rrddeftree_t *)malloc(sizeof(rrddeftree_t)); newrec->key = key; newrec->defs = defs; newrec->count = defcount; xtreeAdd(rrddeftree, newrec->key, newrec); key = NULL; defs = NULL; defcount = 0; } key = strdup(STRBUF(inbuf)+1); p = strchr(key, ']'); if (p) *p = '\0'; } else if (key) { if (!defs) { defcount = 1; defs = (char **)malloc(sizeof(char *)); } else { defcount++; defs = (char **)realloc(defs, defcount * sizeof(char *)); } p = STRBUF(inbuf); p += strspn(p, " \t"); defs[defcount-1] = strdup(p); } } if (key && (defcount > 0)) { /* Save the last record */ newrec = (rrddeftree_t *)malloc(sizeof(rrddeftree_t)); newrec->key = key; newrec->defs = defs; newrec->count = defcount; xtreeAdd(rrddeftree, newrec->key, newrec); } stackfclose(fd); loaddone: freestrbuffer(inbuf); /* Check if the default record exists */ if (xtreeFind(rrddeftree, "") == xtreeEnd(rrddeftree)) { /* Create the default record */ newrec = (rrddeftree_t *)malloc(sizeof(rrddeftree_t)); newrec->key = strdup(""); newrec->defs = (char **)malloc(4 * sizeof(char *));; newrec->defs[0] = strdup("RRA:AVERAGE:0.5:1:576"); newrec->defs[1] = strdup("RRA:AVERAGE:0.5:6:576"); newrec->defs[2] = strdup("RRA:AVERAGE:0.5:24:576"); newrec->defs[3] = strdup("RRA:AVERAGE:0.5:288:576"); newrec->count = 4; xtreeAdd(rrddeftree, newrec->key, newrec); } }