/* Return the simple name of the host */ char * getsname(register u_int32_t a) { register char *s, *cp; s = gethname(a); if (!isdigit((int)*s)) { cp = strchr(s, '.'); if (cp != NULL) *cp = '\0'; } return (s); }
static long evaluate(char *symbolicexpr, char **resultexpr, value_t **valuelist, char **errbuf) { char expr[MAX_LINE_LEN]; char *inp, *outp, *symp; char symbol[MAX_LINE_LEN]; int done; int insymbol = 0; int result, error; long oneval; int onecolor; value_t *valhead = NULL, *valtail = NULL; value_t *newval; char errtext[1024]; done = 0; inp=symbolicexpr; outp=expr; symp = NULL; while (!done) { if (isalpha((int)*inp) || (isdigit((int)*inp) && insymbol && *(inp+1) && (*(inp+1) > ' ') && *(inp+2) && (*(inp+2) > ' ')) ) { /* puke */ if (!insymbol) { insymbol = 1; symp = symbol; } *symp = *inp; symp++; } else if (insymbol && (isdigit((int) *inp) || (*inp == '.'))) { *symp = *inp; symp++; } else if (insymbol && ((*inp == '\\') && (*(inp+1) > ' '))) { *symp = *(inp+1); symp++; inp++; } else { if (insymbol) { /* Symbol finished - evaluate the symbol */ char *hname, *tname; *symp = '\0'; insymbol = 0; hname = gethname(symbol); tname = gettname(symbol); if (hname && tname) { oneval = getvalue(gethname(symbol), gettname(symbol), &onecolor, errbuf); if (oneval == -1) { dbgprintf("Forward lookup of '%s.%s' pending for '%s'\n", hname, tname, symbolicexpr); return -1; } } else { errprintf("Invalid data for symbol calculation - missing host/testname: %s\n", symbol); oneval = 0; onecolor = COL_CLEAR; } sprintf(outp, "%ld", oneval); outp += strlen(outp); newval = (value_t *) malloc(sizeof(value_t)); newval->symbol = strdup(symbol); newval->color = onecolor; newval->next = NULL; if (valhead == NULL) { valtail = valhead = newval; } else { valtail->next = newval; valtail = newval; } } *outp = *inp; outp++; symp = NULL; } if (*inp == '\0') done = 1; else inp++; } *outp = '\0'; if (resultexpr) *resultexpr = strdup(expr); dbgprintf("Symbolic '%s' converted to '%s'\n", symbolicexpr, expr); error = 0; result = compute(expr, &error); if (error) { sprintf(errtext, "compute(%s) returned error %d\n", expr, error); if (*errbuf == NULL) { *errbuf = strdup(errtext); } else { *errbuf = (char *)realloc(*errbuf, strlen(*errbuf)+strlen(errtext)+1); strcat(*errbuf, errtext); } } *valuelist = valhead; return result; }
int update_combotests(int showeval, int cleanexpr) { testspec_t *t; int pending; int remaining = 0; init_timestamp(); loadtests(); /* * Loop over the tests to allow us "forward refs" in expressions. * We continue for as long as progress is being made. */ remaining = testcount; do { pending = remaining; for (t=testhead; (t); t = t->next) { if (t->result == -1) { t->result = evaluate(t->expression, &t->resultexpr, &t->valuelist, &t->errbuf); if (t->result != -1) remaining--; } } } while (pending != remaining); combo_start(); for (t=testhead; (t); t = t->next) { char msgline[MAX_LINE_LEN]; int color; value_t *vwalk; color = (t->result ? COL_GREEN : COL_RED); init_status(color); sprintf(msgline, "status %s.%s %s %s\n\n", commafy(t->reshostname), ( t->restestname ? t->restestname : "combostatuserror" ), colorname(color), timestamp); addtostatus(msgline); if (t->comment) { addtostatus(t->comment); addtostatus("\n\n"); } if (showeval) { addtostatus(printify(t->expression, cleanexpr)); addtostatus(" = "); addtostatus(printify(t->resultexpr, cleanexpr)); addtostatus(" = "); sprintf(msgline, "%ld\n", t->result); addtostatus(msgline); for (vwalk = t->valuelist; (vwalk); vwalk = vwalk->next) { sprintf(msgline, "&%s <a href=\"%s/svcstatus.sh?HOST=%s&SERVICE=%s\">%s</a>\n", colorname(vwalk->color), xgetenv("CGIBINURL"), textornull(gethname(vwalk->symbol)), textornull(gettname(vwalk->symbol)), textornull(vwalk->symbol)); addtostatus(msgline); } if (t->errbuf) { addtostatus("\nErrors occurred during evaluation:\n"); addtostatus(t->errbuf); } } finish_status(); } combo_end(); return 0; }
static void loadtests(void) { static time_t lastupdate = 0; static char *fn = NULL; struct stat st; FILE *fd; strbuffer_t *inbuf; if (!fn) { fn = (char *)malloc(1024 + strlen(xgetenv("XYMONHOME"))); *fn = '\0'; } sprintf(fn, "%s/etc/combo.cfg", xgetenv("XYMONHOME")); if ((stat(fn, &st) == 0) && (st.st_mtime == lastupdate)) return; lastupdate = st.st_mtime; fd = stackfopen(fn, "r", NULL); if (fd == NULL) { errprintf("Cannot open %s/combo.cfg\n", xgetenv("XYMONHOME")); *fn = '\0'; return; } flush_testlist(); inbuf = newstrbuffer(0); while (stackfgets(inbuf, NULL)) { char *p, *comment; char *inp, *outp; p = strchr(STRBUF(inbuf), '\n'); if (p) *p = '\0'; /* Strip whitespace */ for (inp=outp=STRBUF(inbuf); ((*inp >= ' ') && (*inp != '#')); inp++) { if (isspace((int)*inp)) { } else { *outp = *inp; outp++; } } *outp = '\0'; if (strlen(inp)) memmove(outp, inp, strlen(inp)+1); strbufferrecalc(inbuf); if (STRBUFLEN(inbuf) && (*STRBUF(inbuf) != '#') && (p = strchr(STRBUF(inbuf), '=')) ) { testspec_t *newtest; char *hname, *tname; hname = gethname(STRBUF(inbuf)); tname = gettname(STRBUF(inbuf)); if (hname && tname) { *p = '\0'; comment = strchr(p+1, '#'); if (comment) *comment = '\0'; newtest = (testspec_t *) malloc(sizeof(testspec_t)); newtest->reshostname = strdup(gethname(STRBUF(inbuf))); newtest->restestname = strdup(gettname(STRBUF(inbuf))); newtest->expression = strdup(p+1); newtest->comment = (comment ? strdup(comment+1) : NULL); newtest->resultexpr = NULL; newtest->valuelist = NULL; newtest->result = -1; newtest->errbuf = NULL; newtest->next = testhead; testhead = newtest; testcount++; } else { errprintf("Invalid combo test %s - missing host/test names. Perhaps you need to escape dashes?\n", STRBUF(inbuf)); } } } stackfclose(fd); freestrbuffer(inbuf); }