void send_data(void *host, char *beadomain, char *databuf, char **items) { bea_idx_t *idxwalk; strbuffer_t *msgbuf; char *p; int i; msgbuf = newstrbuffer(0); for (idxwalk = bea_idxhead; (idxwalk); idxwalk = idxwalk->next) { sprintf(msgline, "data %s.bea\n\n", commafy(bbh_item(host, BBH_HOSTNAME))); addtobuffer(msgbuf, msgline); if (beadomain && *beadomain) { sprintf(msgline, "DOMAIN:%s\n", beadomain); addtobuffer(msgbuf, msgline); } for (i=0; (items[i]); i++) { p = getstring(databuf, idxwalk->idx, items[i]); sprintf(msgline, "%s\n", p); addtobuffer(msgbuf, msgline); } sendmessage(STRBUF(msgbuf), NULL, BBTALK_TIMEOUT, NULL); clearstrbuffer(msgbuf); } freestrbuffer(msgbuf); }
void init_status(int color) { if (msgbuf == NULL) msgbuf = newstrbuffer(0); clearstrbuffer(msgbuf); msgcolor = color; xymonstatuscount++; }
char *htmlquoted(char *s) { /* * This routine converts a plain string into an html-quoted string */ static strbuffer_t *result = NULL; char *inp, *endp; char c; if (!result) result = newstrbuffer(4096); clearstrbuffer(result); inp = s; do { endp = inp + strcspn(inp, "\"&<> "); c = *endp; if (endp > inp) addtobufferraw(result, inp, endp-inp); switch (c) { case '"': addtobuffer(result, """); break; case '&': addtobuffer(result, "&"); break; case '<': addtobuffer(result, "<"); break; case '>': addtobuffer(result, ">"); break; case ' ': addtobuffer(result, " "); break; default: break; } inp = (c == '\0') ? NULL : endp+1; } while (inp); return STRBUF(result); }
static int prepare_fromfile(char *hostsfn, char *extrainclude) { static void *hostfiles = NULL; FILE *hosts; strbuffer_t *inbuf; /* First check if there were no modifications at all */ if (hostfiles) { if (!stackfmodified(hostfiles)){ return 1; } else { stackfclist(&hostfiles); hostfiles = NULL; } } if (!contentbuffer) contentbuffer = newstrbuffer(0); clearstrbuffer(contentbuffer); hosts = stackfopen(hostsfn, "r", &hostfiles); if (hosts == NULL) return -1; inbuf = newstrbuffer(0); while (stackfgets(inbuf, extrainclude)) { sanitize_input(inbuf, 0, 0); addtostrbuffer(contentbuffer, inbuf); addtobuffer(contentbuffer, "\n"); } stackfclose(hosts); freestrbuffer(inbuf); return 0; }
void senddata(conn_t *conn) { /* Write data to a peer connection (client or server) */ int n, togo; char *startp; togo = STRBUFLEN(conn->msgbuf) - conn->sentbytes; startp = STRBUF(conn->msgbuf) + conn->sentbytes; n = write(conn->sockfd, startp, togo); if (n == -1) { /* Write failure. Also happens if connecting to peer fails */ time_t now = time(NULL); if (debug || (conn->client->nexterrortxt < now)) { errprintf("Connection lost during connect/write to %s (req %lu): %s\n", addrstring(&conn->caddr), conn->seq, strerror(errno)); conn->client->nexterrortxt = now + errorloginterval; } flag_cleanup(conn); } else if (n >= 0) { dbgprintf("Sent %d bytes to %s (req %lu)\n", n, addrstring(&conn->caddr), conn->seq); conn->sentbytes += n; if (conn->sentbytes == STRBUFLEN(conn->msgbuf)) { /* Everything has been sent, so switch to READ mode */ clearstrbuffer(conn->msgbuf); shutdown(conn->sockfd, SHUT_WR); conn->action = C_READING; } } }
static void result_plain(myconn_t *rec, strbuffer_t *txt) { char msgline[4096]; if (dontsendmessages >= 1) { if (rec->textlog) clearstrbuffer(rec->textlog); return; } if (rec->textlog) { snprintf(msgline, sizeof(msgline), "PLAINlog: %d\n", STRBUFLEN(rec->textlog)); addtobuffer(txt, msgline); addtostrbuffer(txt, rec->textlog); addtobuffer(txt, "\n"); clearstrbuffer(rec->textlog); } }
void combo_start(void) { combo_params(); if (xymonmsg == NULL) xymonmsg = newstrbuffer(0); clearstrbuffer(xymonmsg); addtobuffer(xymonmsg, "combo\n"); xymonmsgqueued = 0; }
static void result_subqueue(char *id, myconn_t *rec, strbuffer_t *txt) { char msgline[4096]; if (rec->textlog) { snprintf(msgline, sizeof(msgline), "%slog: %d\n", id, STRBUFLEN(rec->textlog)); addtobuffer(txt, msgline); addtostrbuffer(txt, rec->textlog); addtobuffer(txt, "\n"); clearstrbuffer(rec->textlog); } }
static void result_http(myconn_t *rec, strbuffer_t *txt) { char msgline[4096]; snprintf(msgline, sizeof(msgline), "HTTPstatus: %d\n", rec->httpstatus); addtobuffer(txt, msgline); if (dontsendmessages >= 2) { if (rec->textlog) clearstrbuffer(rec->textlog); if (rec->httpheaders) clearstrbuffer(rec->httpheaders); if (rec->httpbody) clearstrbuffer(rec->httpbody); return; } if (rec->redircount) { snprintf(msgline, sizeof(msgline), "Redirects: %d\n", rec->redircount); addtobuffer(txt, msgline); } if (rec->textlog) { char *authtoken; snprintf(msgline, sizeof(msgline), "HTTPrequest: %d\n", STRBUFLEN(rec->textlog)); addtobuffer(txt, msgline); /* * If there is an authentication header, it is best to obscure it here. * Otherwise, anyone who can view the "client data" will be able to see * the login. */ authtoken = strstr(STRBUF(rec->textlog), "\nAuthorization:"); if (authtoken) { authtoken += 15; while (*authtoken != '\r') { *authtoken = '*'; authtoken++; } } addtostrbuffer(txt, rec->textlog); addtobuffer(txt, "\n"); clearstrbuffer(rec->textlog); } if (rec->httpheaders) { snprintf(msgline, sizeof(msgline), "HTTPheaders: %d\n", STRBUFLEN(rec->httpheaders)); addtobuffer(txt, msgline); addtostrbuffer(txt, rec->httpheaders); addtobuffer(txt, "\n"); clearstrbuffer(rec->httpheaders); } if (rec->httpbody) { snprintf(msgline, sizeof(msgline), "HTTPbody: %d\n", STRBUFLEN(rec->httpbody)); addtobuffer(txt, msgline); addtostrbuffer(txt, rec->httpbody); addtobuffer(txt, "\n"); clearstrbuffer(rec->httpbody); } }
static char *preprocess(char *buf) { /* Expands config-file macros */ static strbuffer_t *result = NULL; char *inp; if (result == NULL) result = newstrbuffer(8192); clearstrbuffer(result); inp = buf; while (inp) { char *p; p = strchr(inp, '$'); if (p == NULL) { addtobuffer(result, inp); inp = NULL; } else { token_t *twalk; char savech; int n; *p = '\0'; addtobuffer(result, inp); p = (p+1); n = strcspn(p, "\t $.,|%!()[]{}+?/&@:;*"); savech = *(p+n); *(p+n) = '\0'; for (twalk = tokhead; (twalk && strcmp(p, twalk->name)); twalk = twalk->next) ; *(p+n) = savech; if (twalk) addtobuffer(result, twalk->value); inp = p+n; } } return STRBUF(result); }
char *unlimfgets(strbuffer_t *buffer, FILE *fd) { fgetsbuf_t *fg; size_t n; char *eoln = NULL; for (fg = fgetshead; (fg && (fg->fd != fd)); fg = fg->next) ; if (!fg) { errprintf("umlimfgets() called with bad input FD\n"); return NULL; } /* End of file ? */ if (!(fg->moretoread) && (*(fg->inbufp) == '\0')) { if (fg == fgetshead) { fgetshead = fgetshead->next; free(fg); } else { fgetsbuf_t *prev; for (prev = fgetshead; (prev->next != fg); prev = prev->next) ; prev->next = fg->next; free(fg); } return NULL; } /* Make sure the output buffer is empty */ clearstrbuffer(buffer); while (!eoln && (fg->moretoread || *(fg->inbufp))) { int continued = 0; if (*(fg->inbufp)) { /* Have some data in the buffer */ eoln = strchr(fg->inbufp, '\n'); if (eoln) { /* See if there's a continuation character just before the eoln */ char *contchar = eoln-1; while ((contchar > fg->inbufp) && isspace((int)*contchar) && (*contchar != '\\')) contchar--; continued = (*contchar == '\\'); if (continued) { *contchar = '\0'; addtobuffer(buffer, fg->inbufp); fg->inbufp = eoln+1; eoln = NULL; } else { char savech = *(eoln+1); *(eoln+1) = '\0'; addtobuffer(buffer, fg->inbufp); *(eoln+1) = savech; fg->inbufp = eoln+1; } } else { /* No newline in buffer, so add all of it to the output buffer */ addtobuffer(buffer, fg->inbufp); /* Input buffer is now empty */ *(fg->inbuf) = '\0'; fg->inbufp = fg->inbuf; } } if (!eoln && !continued) { /* Get data for the input buffer */ char *inpos = fg->inbuf; size_t insize = sizeof(fg->inbuf); /* If the last byte we read was a continuation char, we must do special stuff. * * Mike Romaniw discovered that if we hit an input with a newline exactly at * the point of a buffer refill, then strlen(*buffer) is 0, and contchar then * points before the start of the buffer. Bad. But this can only happen when * the previous char WAS a newline, and hence it is not a continuation line. * So the simple fix is to only do the cont-char stuff if **buffer is not NUL. * Hence the test for both *buffer and **buffer. */ if (STRBUF(buffer) && *STRBUF(buffer)) { char *contchar = STRBUF(buffer) + STRBUFLEN(buffer) - 1; while ((contchar > STRBUF(buffer)) && isspace((int)*contchar) && (*contchar != '\\')) contchar--; if (*contchar == '\\') { /* * Remove the cont. char from the output buffer, and stuff it into * the input buffer again - so we can check if there's a new-line coming. */ strbufferchop(buffer, 1); *(fg->inbuf) = '\\'; inpos++; insize--; } } n = fread(inpos, 1, insize-1, fd); *(inpos + n) = '\0'; fg->inbufp = fg->inbuf; if (n < insize-1) fg->moretoread = 0; } } return STRBUF(buffer); }
int main(int argc, char *argv[]) { void *hwalk; char *hostsfn = NULL; char *netstring = NULL; char *include2 = NULL; int extras = 1; int testuntagged = 0; int nodownhosts = 0; int onlypreferredentry = 0; char *p; char **lookv; int argi, lookc; strbuffer_t *wantedtags; if ((argc <= 1) || (strcmp(argv[1], "--help") == 0)) { printf("Usage:\n%s test1 [test1] [test2] ... \n", argv[0]); exit(1); } lookv = (char **)malloc(argc*sizeof(char *)); lookc = 0; hostsfn = xgetenv("HOSTSCFG"); conncolumn = xgetenv("PINGCOLUMN"); for (argi=1; (argi < argc); argi++) { if (strcmp(argv[argi], "--noextras") == 0) { extras = 0; } else if (strcmp(argv[argi], "--test-untagged") == 0) { testuntagged = 1; } else if (argnmatch(argv[argi], "--no-down")) { char *p; nodownhosts = 1; p = strchr(argv[argi], '='); if (p) testcolumn = strdup(p+1); } else if (strcmp(argv[argi], "--version") == 0) { printf("xymongrep version %s\n", VERSION); exit(0); } else if ((strcmp(argv[argi], "--net") == 0) || (strcmp(argv[argi], "--bbnet") == 0)) { include2 = "netinclude"; onlypreferredentry = 0; } else if ((strcmp(argv[argi], "--web") == 0) || (strcmp(argv[argi], "--bbdisp") == 0)) { include2 = "dispinclude"; onlypreferredentry = 1; } else if (argnmatch(argv[argi], "--hosts=")) { hostsfn = strchr(argv[argi], '=') + 1; } else { lookv[lookc] = strdup(argv[argi]); lookc++; } } lookv[lookc] = NULL; if ((hostsfn == NULL) || (strlen(hostsfn) == 0)) { errprintf("Environment variable HOSTSCFG is not set - aborting\n"); exit(2); } load_hostnames(hostsfn, include2, get_fqdn()); if (first_host() == NULL) { errprintf("Cannot load %s, or file is empty\n", hostsfn); exit(3); } /* If we must avoid downed or disabled hosts, let's find out what those are */ if (nodownhosts) load_hoststatus(); /* Each network test tagged with NET:locationname */ p = xgetenv("XYMONNETWORK"); if ((p == NULL) || (strlen(p) == 0)) p = xgetenv("BBLOCATION"); if (p && strlen(p)) netstring = strdup(p); hwalk = first_host(); wantedtags = newstrbuffer(0); while (hwalk) { char hostip[IP_ADDR_STRLEN]; char *curnet = xmh_item(hwalk, XMH_NET); char *curname = xmh_item(hwalk, XMH_HOSTNAME); /* * Only look at the hosts whose NET: definition matches the wanted one. * Must also check if the host is currently down (not responding to ping). * And if the host is OK with knownhost(), because it may be time-limited. */ if (netok(netstring, curnet, testuntagged) && downok(curname, nodownhosts) && knownhost(curname, hostip, GH_IGNORE)) { char *item; clearstrbuffer(wantedtags); for (item = xmh_item_walk(hwalk); (item); item = xmh_item_walk(NULL)) { int i; char *realitem = item + strspn(item, "!~?"); for (i=0; lookv[i]; i++) { char *outitem = NULL; if (lookv[i][strlen(lookv[i])-1] == '*') { if (strncasecmp(realitem, lookv[i], strlen(lookv[i])-1) == 0) { outitem = (extras ? item : realitem); } } else if (strcasecmp(realitem, lookv[i]) == 0) { outitem = (extras ? item : realitem); } if (outitem) { int needquotes = ((strchr(outitem, ' ') != NULL) || (strchr(outitem, '\t') != NULL)); addtobuffer(wantedtags, " "); if (needquotes) addtobuffer(wantedtags, "\""); addtobuffer(wantedtags, outitem); if (needquotes) addtobuffer(wantedtags, "\""); } } } if (STRBUF(wantedtags) && (*STRBUF(wantedtags) != '\0') && extras) { if (xmh_item(hwalk, XMH_FLAG_DIALUP)) addtobuffer(wantedtags, " dialup"); if (xmh_item(hwalk, XMH_FLAG_TESTIP)) addtobuffer(wantedtags, " testip"); } if (STRBUF(wantedtags) && *STRBUF(wantedtags)) { printf("%s %s #%s\n", xmh_item(hwalk, XMH_IP), xmh_item(hwalk, XMH_HOSTNAME), STRBUF(wantedtags)); } } do { hwalk = next_host(hwalk, 1); } while (hwalk && onlypreferredentry && (strcmp(curname, xmh_item(hwalk, XMH_HOSTNAME)) == 0)); } return 0; }
char *timespec_text(char *spec) { static char *daynames[7] = { NULL, }; static char *wkdays = NULL; static strbuffer_t *result = NULL; char *sCopy; char *sItem; if (result == NULL) result = newstrbuffer(0); clearstrbuffer(result); if (!daynames[0]) { /* Use strftime to get the locale-specific weekday names */ time_t now; int i; now = time(NULL); for (i=0; (i<7); i++) { char dtext[10]; struct tm *tm = localtime(&now); strftime(dtext, sizeof(dtext), "%a", tm); daynames[tm->tm_wday] = strdup(dtext); now -= 86400; } wkdays = (char *)malloc(strlen(daynames[1]) + strlen(daynames[5]) + 2); sprintf(wkdays, "%s-%s", daynames[1], daynames[5]); } sCopy = strdup(spec); sItem = strtok(sCopy, ","); while (sItem) { char *oneday, *dtext; int daysdone = 0, firstday = 1; oneday = sItem; while (!daysdone) { switch (*oneday) { case '*': dtext = "All days"; break; case 'W': dtext = wkdays; break; case '0': dtext = daynames[0]; break; case '1': dtext = daynames[1]; break; case '2': dtext = daynames[2]; break; case '3': dtext = daynames[3]; break; case '4': dtext = daynames[4]; break; case '5': dtext = daynames[5]; break; case '6': dtext = daynames[6]; break; default : dtext = oneday; daysdone = firstday = 1; break; } if (!firstday) addtobuffer(result, "/"); addtobuffer(result, dtext); oneday++; firstday = 0; } sItem = strtok(NULL, ","); if (sItem) addtobuffer(result, ", "); } xfree(sCopy); return STRBUF(result); }
void meta_start(void) { if (metamsg == NULL) metamsg = newstrbuffer(0); clearstrbuffer(metamsg); xymonmetaqueued = 0; }
int main(int argc, char *argv[]) { void *hwalk; int argi; strbuffer_t *statusmsg, *jrockout, *qout; for (argi = 1; (argi < argc); argi++) { if ((strcmp(argv[argi], "--help") == 0)) { printf("beastat version %s\n\n", VERSION); printf("Usage:\n%s [--debug] [--no-update] [--port=SNMPPORT] [--community=SNMPCOMMUNITY]\n", argv[0]); exit(0); } else if ((strcmp(argv[argi], "--version") == 0)) { printf("beastat version %s\n", VERSION); exit(0); } else if ((strcmp(argv[argi], "--debug") == 0)) { debug = 1; } else if ((strcmp(argv[argi], "--no-update") == 0)) { dontsendmessages = 1; } else if (argnmatch(argv[argi], "--timeout=")) { char *p = strchr(argv[argi], '='); extcmdtimeout = atoi(p+1); } else if (argnmatch(argv[argi], "--port=")) { char *p = strchr(argv[argi], '='); default_port = atoi(p+1); } else if (argnmatch(argv[argi], "--community=")) { char *p = strchr(argv[argi], '='); default_community = strdup(p+1); } } load_hostnames(xgetenv("BBHOSTS"), "netinclude", get_fqdn()); if (first_host() == NULL) { errprintf("Cannot load bb-hosts\n"); return 1; } if (xgetenv("BBLOCATION")) location = strdup(xgetenv("BBLOCATION")); init_timestamp(); combo_start(); statusmsg = newstrbuffer(0); jrockout = newstrbuffer(0); qout = newstrbuffer(0); for (hwalk = first_host(); (hwalk); hwalk = next_host(hwalk, 0)) { char *tspec = bbh_custom_item(hwalk, "bea="); char *snmpcommunity = default_community; char *beadomain = ""; int snmpport = default_port; char *p; char pipecmd[4096]; int jrockres, qres; clearstrbuffer(statusmsg); clearstrbuffer(jrockout); clearstrbuffer(qout); /* Check if we have a "bea" test for this host, and it is a host we want to test */ if (!tspec || !wanted_host(hwalk, location)) continue; /* Parse the testspec: bea=[SNMPCOMMUNITY@]BEADOMAIN[:SNMPPORT] */ tspec = strdup(tspec+strlen("bea=")); p = strchr(tspec, ':'); if (p) { *p = '\0'; snmpport = atoi(p+1); } p = strchr(tspec, '@'); if (p) { *p = '\0'; snmpcommunity = strdup(tspec); beadomain = strdup(p+1); } else { beadomain = strdup(tspec); } /* Prepare for the host status */ statuscolor = COL_GREEN; /* Setup the snmpwalk pipe-command for jrockit stats */ sprintf(pipecmd, "snmpwalk -m BEA-WEBLOGIC-MIB -c %s@%s -v 1 %s:%d enterprises.140.625.302.1", snmpcommunity, beadomain, bbh_item(hwalk, BBH_IP), snmpport); jrockres = run_command(pipecmd, NULL, jrockout, 0, extcmdtimeout); if (jrockres == 0) { find_idxes(STRBUF(jrockout), "BEA-WEBLOGIC-MIB::jrockitRuntimeIndex."); send_data(hwalk, beadomain, STRBUF(jrockout), jrockitems); } else { if (statuscolor < COL_YELLOW) statuscolor = COL_YELLOW; sprintf(msgline, "Could not retrieve BEA jRockit statistics from %s:%d domain %s (code %d)\n", bbh_item(hwalk, BBH_IP), snmpport, beadomain, jrockres); addtobuffer(statusmsg, msgline); } /* Setup the snmpwalk pipe-command for executeQueur stats */ sprintf(pipecmd, "snmpwalk -m BEA-WEBLOGIC-MIB -c %s@%s -v 1 %s:%d enterprises.140.625.180.1", snmpcommunity, beadomain, bbh_item(hwalk, BBH_IP), snmpport); qres = run_command(pipecmd, NULL, qout, 0, extcmdtimeout); if (qres == 0) { find_idxes(STRBUF(qout), "BEA-WEBLOGIC-MIB::executeQueueRuntimeIndex."); send_data(hwalk, beadomain, STRBUF(qout), qitems); } else { if (statuscolor < COL_YELLOW) statuscolor = COL_YELLOW; sprintf(msgline, "Could not retrieve BEA executeQueue statistics from %s:%d domain %s (code %d)\n", bbh_item(hwalk, BBH_IP), snmpport, beadomain, qres); addtobuffer(statusmsg, msgline); } /* FUTURE: Have the statuscolor/statusmsg be updated to check against thresholds */ /* Right now, the "bea" status is always green */ init_status(statuscolor); sprintf(msgline, "status %s.%s %s %s\n\n", commafy(bbh_item(hwalk, BBH_HOSTNAME)), "bea", colorname(statuscolor), timestamp); addtostatus(msgline); if (STRBUFLEN(statusmsg) == 0) addtobuffer(statusmsg, "All BEA monitors OK\n"); addtostrstatus(statusmsg); finish_status(); } combo_end(); freestrbuffer(statusmsg); freestrbuffer(jrockout); freestrbuffer(qout); return 0; }
void dns_detail_callback(void *arg, int status, int timeouts, unsigned char *abuf, int alen) { int id, qr, opcode, aa, tc, rd, ra, rcode; unsigned int qdcount, ancount, nscount, arcount, i; const unsigned char *aptr; dns_resp_t *response = (dns_resp_t *) arg; clearstrbuffer(response->msgbuf); response->msgstatus = status; /* * Display an error message if there was an error, but only stop if * we actually didn't get an answer buffer. */ switch (status) { case ARES_SUCCESS: break; case ARES_ENODATA: addtobuffer(response->msgbuf, "No data returned from server\n"); if (!abuf) return; break; case ARES_EFORMERR: addtobuffer(response->msgbuf, "Server could not understand query\n"); if (!abuf) return; break; case ARES_ESERVFAIL: addtobuffer(response->msgbuf, "Server failed\n"); if (!abuf) return; break; case ARES_ENOTFOUND: addtobuffer(response->msgbuf, "Name not found\n"); if (!abuf) return; break; case ARES_ENOTIMP: addtobuffer(response->msgbuf, "Not implemented\n"); if (!abuf) return; break; case ARES_EREFUSED: addtobuffer(response->msgbuf, "Server refused query\n"); if (!abuf) return; break; case ARES_EBADNAME: addtobuffer(response->msgbuf, "Invalid name in query\n"); if (!abuf) return; break; case ARES_ETIMEOUT: addtobuffer(response->msgbuf, "Timeout\n"); if (!abuf) return; break; case ARES_ECONNREFUSED: addtobuffer(response->msgbuf, "Server unavailable\n"); if (!abuf) return; break; case ARES_ENOMEM: addtobuffer(response->msgbuf, "Out of memory\n"); if (!abuf) return; break; case ARES_EDESTRUCTION: addtobuffer(response->msgbuf, "Timeout (channel destroyed)\n"); if (!abuf) return; break; default: addtobuffer(response->msgbuf, "Undocumented ARES return code\n"); if (!abuf) return; break; } /* Won't happen, but check anyway, for safety. */ if (alen < HFIXEDSZ) return; /* Parse the answer header. */ id = DNS_HEADER_QID(abuf); qr = DNS_HEADER_QR(abuf); opcode = DNS_HEADER_OPCODE(abuf); aa = DNS_HEADER_AA(abuf); tc = DNS_HEADER_TC(abuf); rd = DNS_HEADER_RD(abuf); ra = DNS_HEADER_RA(abuf); rcode = DNS_HEADER_RCODE(abuf); qdcount = DNS_HEADER_QDCOUNT(abuf); ancount = DNS_HEADER_ANCOUNT(abuf); nscount = DNS_HEADER_NSCOUNT(abuf); arcount = DNS_HEADER_ARCOUNT(abuf); /* Display the answer header. */ sprintf(msg, "id: %d\n", id); addtobuffer(response->msgbuf, msg); sprintf(msg, "flags: %s%s%s%s%s\n", qr ? "qr " : "", aa ? "aa " : "", tc ? "tc " : "", rd ? "rd " : "", ra ? "ra " : ""); addtobuffer(response->msgbuf, msg); sprintf(msg, "opcode: %s\n", opcodes[opcode]); addtobuffer(response->msgbuf, msg); sprintf(msg, "rcode: %s\n", rcodes[rcode]); addtobuffer(response->msgbuf, msg); /* Display the questions. */ addtobuffer(response->msgbuf, "Questions:\n"); aptr = abuf + HFIXEDSZ; for (i = 0; i < qdcount; i++) { aptr = display_question(aptr, abuf, alen, response); if (aptr == NULL) return; } /* Display the answers. */ addtobuffer(response->msgbuf, "Answers:\n"); for (i = 0; i < ancount; i++) { aptr = display_rr(aptr, abuf, alen, response); if (aptr == NULL) return; } /* Display the NS records. */ addtobuffer(response->msgbuf, "NS records:\n"); for (i = 0; i < nscount; i++) { aptr = display_rr(aptr, abuf, alen, response); if (aptr == NULL) return; } /* Display the additional records. */ addtobuffer(response->msgbuf, "Additional records:\n"); for (i = 0; i < arcount; i++) { aptr = display_rr(aptr, abuf, alen, response); if (aptr == NULL) return; } return; }
int main(int argc, char *argv[]) { char *msg; int running; int argi, seq; struct timespec *timeout = NULL; pcre *hostexp = NULL; pcre *exhostexp = NULL; pcre *testexp = NULL; pcre *extestexp = NULL; pcre *colorexp = NULL; const char *errmsg = NULL; int errofs = 0; FILE *logfd = stdout; int batchtimeout = 30; char *batchcmd = NULL; strbuffer_t *batchbuf = NULL; time_t lastmsgtime = 0; /* Handle program options. */ for (argi = 1; (argi < argc); argi++) { if (strcmp(argv[argi], "--debug") == 0) { /* * A global "debug" variable is available. If * it is set, then "dbgprintf()" outputs debug messages. */ debug = 1; } else if (strncmp(argv[argi], "--timeout=", 10) == 0) { /* * You can have a timeout when waiting for new * messages. If it happens, you will get a "@@idle\n" * message with sequence number 0. * If you dont want a timeout, just pass a NULL for the timeout parameter. */ timeout = (struct timespec *)(malloc(sizeof(struct timespec))); timeout->tv_sec = (atoi(argv[argi]+10)); timeout->tv_nsec = 0; } else if (argnmatch(argv[argi], "--hosts=")) { char *exp = strchr(argv[argi], '=') + 1; hostexp = pcre_compile(exp, PCRE_CASELESS, &errmsg, &errofs, NULL); if (hostexp == NULL) printf("Invalid expression '%s'\n", exp); } else if (argnmatch(argv[argi], "--exhosts=")) { char *exp = strchr(argv[argi], '=') + 1; exhostexp = pcre_compile(exp, PCRE_CASELESS, &errmsg, &errofs, NULL); if (exhostexp == NULL) printf("Invalid expression '%s'\n", exp); } else if (argnmatch(argv[argi], "--tests=")) { char *exp = strchr(argv[argi], '=') + 1; testexp = pcre_compile(exp, PCRE_CASELESS, &errmsg, &errofs, NULL); if (testexp == NULL) printf("Invalid expression '%s'\n", exp); } else if (argnmatch(argv[argi], "--extests=")) { char *exp = strchr(argv[argi], '=') + 1; extestexp = pcre_compile(exp, PCRE_CASELESS, &errmsg, &errofs, NULL); if (extestexp == NULL) printf("Invalid expression '%s'\n", exp); } else if (argnmatch(argv[argi], "--colors=")) { char *exp = strchr(argv[argi], '=') + 1; colorexp = pcre_compile(exp, PCRE_CASELESS, &errmsg, &errofs, NULL); if (colorexp == NULL) printf("Invalid expression '%s'\n", exp); } else if (argnmatch(argv[argi], "--outfile=")) { char *fn = strchr(argv[argi], '=') + 1; logfd = fopen(fn, "a"); if (logfd == NULL) { printf("Cannot open logfile %s: %s\n", fn, strerror(errno)); logfd = stdout; } } else if (argnmatch(argv[argi], "--batch-timeout=")) { char *p = strchr(argv[argi], '='); batchtimeout = atoi(p+1); timeout = (struct timespec *)(malloc(sizeof(struct timespec))); timeout->tv_sec = batchtimeout; timeout->tv_nsec = 0; } else if (argnmatch(argv[argi], "--batch-command=")) { char *p = strchr(argv[argi], '='); batchcmd = strdup(p+1); batchbuf = newstrbuffer(0); } else { printf("Unknown option %s\n", argv[argi]); printf("Usage: %s [--hosts=EXP] [--tests=EXP] [--exhosts=EXP] [--extests=EXP] [--color=EXP] [--outfile=FILENAME] [--batch-timeout=N] [--batch-command=COMMAND]\n", argv[0]); return 0; } } signal(SIGCHLD, SIG_IGN); running = 1; while (running) { char *eoln, *restofmsg, *p; char *metadata[MAX_META+1]; int metacount; msg = get_hobbitd_message(C_LAST, argv[0], &seq, timeout); if (msg == NULL) { /* * get_hobbitd_message will return NULL if hobbitd_channel closes * the input pipe. We should shutdown when that happens. */ running = 0; continue; } /* * Now we have a message. So do something with it. * * The first line of the message is always a '|' separated * list of meta-data about the message. After the first * line, the content varies by channel. */ /* Split the message in the first line (with meta-data), and the rest */ eoln = strchr(msg, '\n'); if (eoln) { *eoln = '\0'; restofmsg = eoln+1; } else { restofmsg = ""; } /* * Now parse the meta-data into elements. * We use our own "gettok()" routine which works * like strtok(), but can handle empty elements. */ metacount = 0; memset(&metadata, 0, sizeof(metadata)); p = gettok(msg, "|"); while (p && (metacount < MAX_META)) { metadata[metacount++] = p; p = gettok(NULL, "|"); } metadata[metacount] = NULL; /* * A "shutdown" message is sent when the master daemon * terminates. The child workers should shutdown also. */ if (strncmp(metadata[0], "@@shutdown", 10) == 0) { printf("Shutting down\n"); running = 0; continue; } /* * A "logrotate" message is sent when the Hobbit logs are * rotated. The child workers must re-open their logfiles, * typically stdin and stderr - the filename is always * provided in the HOBBITCHANNEL_LOGFILENAME environment. */ else if (strncmp(metadata[0], "@@logrotate", 11) == 0) { char *fn = xgetenv("HOBBITCHANNEL_LOGFILENAME"); if (fn && strlen(fn)) { freopen(fn, "a", stdout); freopen(fn, "a", stderr); } continue; } /* * An "idle" message appears when get_hobbitd_message() * exceeds the timeout setting (ie. you passed a timeout * value). This allows your worker module to perform * some internal processing even though no messages arrive. */ else if (strncmp(metadata[0], "@@idle", 6) == 0) { dbgprintf("Got an 'idle' message\n"); } /* * The "drophost", "droptest", "renamehost" and "renametst" * indicates that a host/test was deleted or renamed. If the * worker module maintains some internal storage (in memory * or persistent file-storage), it should act on these * messages to maintain data consistency. */ else if ((metacount > 3) && (strncmp(metadata[0], "@@drophost", 10) == 0)) { dbgprintf("Got a 'drophost' message for host '%s'\n", metadata[3]); } else if ((metacount > 3) && (strncmp(metadata[0], "@@dropstate", 11) == 0)) { dbgprintf("Got a 'dropstate' message for host '%s'\n", metadata[3]); } else if ((metacount > 4) && (strncmp(metadata[0], "@@droptest", 10) == 0)) { dbgprintf("Got a 'droptest' message for host '%s' test '%s'\n", metadata[3], metadata[4]); } else if ((metacount > 4) && (strncmp(metadata[0], "@@renamehost", 12) == 0)) { dbgprintf("Got a 'renamehost' message for host '%s' -> '%s'\n", metadata[3], metadata[4]); } else if ((metacount > 5) && (strncmp(metadata[0], "@@renametest", 12) == 0)) { dbgprintf("Got a 'renametest' message for host '%s' test '%s' -> '%s'\n", metadata[3], metadata[4], metadata[5]); } /* * Process this message. */ else { int ovector[30]; int match, i; char *hostname = metadata[4]; char *testname = metadata[5]; char *color = metadata[7]; /* See if we should handle the batched messages we've got */ if (batchcmd && ((lastmsgtime + batchtimeout) < gettimer()) && (STRBUFLEN(batchbuf) > 0)) { pid_t childpid = fork(); int childres = 0; if (childpid < 0) { /* Fork failed! */ errprintf("Fork failed: %s\n", strerror(errno)); } else if (childpid == 0) { /* Child */ FILE *cmdpipe = popen(batchcmd, "w"); if (cmdpipe) { /* Write the data to the batch command pipe */ int n, bytesleft = STRBUFLEN(batchbuf); char *outp = STRBUF(batchbuf); while (bytesleft) { n = fwrite(outp, 1, bytesleft, cmdpipe); if (n >= 0) { bytesleft -= n; outp += n; } else { errprintf("Error while writing data to batch command\n"); bytesleft = 0; } } childres = pclose(cmdpipe); } else { errprintf("Could not open pipe to batch command '%s'\n", batchcmd); childres = 127; } exit(childres); } else if (childpid > 0) { /* Parent continues */ } clearstrbuffer(batchbuf); } if (hostexp) { match = (pcre_exec(hostexp, NULL, hostname, strlen(hostname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); if (!match) continue; } if (exhostexp) { match = (pcre_exec(exhostexp, NULL, hostname, strlen(hostname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); if (match) continue; } if (testexp) { match = (pcre_exec(testexp, NULL, testname, strlen(testname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); if (!match) continue; } if (exhostexp) { match = (pcre_exec(extestexp, NULL, testname, strlen(testname), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); if (match) continue; } if (colorexp) { match = (pcre_exec(colorexp, NULL, color, strlen(color), 0, 0, ovector, (sizeof(ovector)/sizeof(int))) >= 0); if (!match) continue; } lastmsgtime = gettimer(); if (batchcmd) { addtobuffer(batchbuf, "## "); for (i=0; (i < metacount); i++) { addtobuffer(batchbuf, metadata[i]); addtobuffer(batchbuf, " "); } addtobuffer(batchbuf, "\n"); addtobuffer(batchbuf, restofmsg); addtobuffer(batchbuf, "\n"); } else { fprintf(logfd, "## "); for (i=0; (i < metacount); i++) fprintf(logfd, "%s ", metadata[i]); fprintf(logfd, "\n"); fprintf(logfd, "%s\n", restofmsg); } } } return 0; }
char *bbh_item(void *hostin, enum bbh_item_t item) { static char *result; static char intbuf[10]; static char *inttxt = NULL; static strbuffer_t *rawtxt = NULL; char *p; namelist_t *host = (namelist_t *)hostin; namelist_t *hwalk; if (rawtxt == NULL) rawtxt = newstrbuffer(0); if (inttxt == NULL) inttxt = (char *)malloc(10); if (host == NULL) return NULL; switch (item) { case BBH_CLIENTALIAS: return host->clientname; case BBH_IP: return host->ip; case BBH_CLASS: if (host->classname) return host->classname; else return bbh_find_item(host, item); break; case BBH_OS: if (host->osname) return host->osname; else return bbh_find_item(host, item); break; case BBH_HOSTNAME: return host->bbhostname; case BBH_PAGENAME: p = strrchr(host->page->pagepath, '/'); if (p) return (p+1); else return host->page->pagepath; case BBH_PAGEPATH: return host->page->pagepath; case BBH_PAGETITLE: p = strrchr(host->page->pagetitle, '/'); if (p) return (p+1); /* else: Fall through */ case BBH_PAGEPATHTITLE: if (strlen(host->page->pagetitle)) return host->page->pagetitle; return "Top Page"; case BBH_PAGEINDEX: sprintf(intbuf, "%d", host->pageindex); return intbuf; case BBH_ALLPAGEPATHS: if (rawtxt) clearstrbuffer(rawtxt); hwalk = host; while (hwalk && (strcmp(hwalk->bbhostname, host->bbhostname) == 0)) { if (STRBUFLEN(rawtxt) > 0) addtobuffer(rawtxt, ","); addtobuffer(rawtxt, hwalk->page->pagepath); hwalk = hwalk->next; } return STRBUF(rawtxt); case BBH_GROUPID: return host->groupid; case BBH_DOCURL: p = bbh_find_item(host, item); if (p) { if (result) xfree(result); result = (char *)malloc(strlen(p) + strlen(host->bbhostname) + 1); sprintf(result, p, host->bbhostname); return result; } else return NULL; case BBH_DOWNTIME: if (host->downtime) return host->downtime; else if (host->defaulthost) return host->defaulthost->downtime; else return NULL; case BBH_RAW: if (rawtxt) clearstrbuffer(rawtxt); p = bbh_item_walk(host); while (p) { addtobuffer(rawtxt, nlencode(p)); p = bbh_item_walk(NULL); if (p) addtobuffer(rawtxt, "|"); } return STRBUF(rawtxt); case BBH_HOLIDAYS: p = bbh_find_item(host, item); if (!p) p = getenv("HOLIDAYS"); return p; case BBH_DATA: return host->data; default: return bbh_find_item(host, item); } return NULL; }
static void zvm_users_report(char *hostname, char *clientclass, enum ostype_t os, void *hinfo, char *fromline, char *timestr, char *psstr) { int pscolor = COL_GREEN; int pchecks; int cmdofs = -1; char msgline[4096]; strbuffer_t *monmsg; static strbuffer_t *countdata = NULL; int anycountdata = 0; char *group; if (!want_msgtype(hinfo, MSG_PROCS)) return; if (!psstr) return; if (!countdata) countdata = newstrbuffer(0); clearalertgroups(); monmsg = newstrbuffer(0); sprintf(msgline, "data %s.proccounts\n", commafy(hostname)); addtobuffer(countdata, msgline); cmdofs = 0; /* Command offset for z/VM isn't necessary */ pchecks = clear_process_counts(hinfo, clientclass); if (pchecks == 0) { /* Nothing to check */ sprintf(msgline, "&%s No process checks defined\n", colorname(noreportcolor)); addtobuffer(monmsg, msgline); pscolor = noreportcolor; } else if (cmdofs >= 0) { /* Count how many instances of each monitored process is running */ char *pname, *pid, *bol, *nl; int pcount, pmin, pmax, pcolor, ptrack; bol = psstr; while (bol) { nl = strchr(bol, '\n'); /* Take care - the ps output line may be shorter than what we look at */ if (nl) { *nl = '\0'; if ((nl-bol) > cmdofs) add_process_count(bol+cmdofs); *nl = '\n'; bol = nl+1; } else { if (strlen(bol) > cmdofs) add_process_count(bol+cmdofs); bol = NULL; } } /* Check the number found for each monitored process */ while ((pname = check_process_count(&pcount, &pmin, &pmax, &pcolor, &pid, &ptrack, &group)) != NULL) { char limtxt[1024]; if (pmax == -1) { if (pmin > 0) sprintf(limtxt, "%d or more", pmin); else if (pmin == 0) sprintf(limtxt, "none"); } else { if (pmin > 0) sprintf(limtxt, "between %d and %d", pmin, pmax); else if (pmin == 0) sprintf(limtxt, "at most %d", pmax); } if (pcolor == COL_GREEN) { sprintf(msgline, "&green %s (found %d, req. %s)\n", pname, pcount, limtxt); addtobuffer(monmsg, msgline); } else { if (pcolor > pscolor) pscolor = pcolor; sprintf(msgline, "&%s %s (found %d, req. %s)\n", colorname(pcolor), pname, pcount, limtxt); addtobuffer(monmsg, msgline); addalertgroup(group); } if (ptrack) { /* Save the count data for later DATA message to track process counts */ if (!pid) pid = "default"; sprintf(msgline, "%s:%u\n", pid, pcount); addtobuffer(countdata, msgline); anycountdata = 1; } } } else { pscolor = COL_YELLOW; sprintf(msgline, "&yellow Expected string not found in ps output header\n"); addtobuffer(monmsg, msgline); } /* Now we know the result, so generate a status message */ init_status(pscolor); group = getalertgroups(); if (group) sprintf(msgline, "status/group:%s ", group); else strcpy(msgline, "status "); addtostatus(msgline); sprintf(msgline, "%s.procs %s %s - Processes %s\n", commafy(hostname), colorname(pscolor), (timestr ? timestr : "<No timestamp data>"), ((pscolor == COL_GREEN) ? "OK" : "NOT ok")); addtostatus(msgline); /* And add the info about what's wrong */ if (STRBUFLEN(monmsg)) { addtostrstatus(monmsg); addtostatus("\n"); } /* And the full virtual machine names output for those who want it */ if (pslistinprocs) { /* * Format the list of virtual machines into four per line, * this list could be fairly long. */ char *tmpstr, *tok, *nm[4]; int nmidx = 0; /* Make a copy of psstr, strtok() will be changing it */ tmpstr = strdup(psstr); /* Use strtok() to split string into pieces delimited by newline */ tok = strtok(tmpstr, "\n"); while (tok) { nm[nmidx++] = tok; if (nmidx == 4) { sprintf(msgline, "%-8s %-8s %-8s %-8s\n", nm[0], nm[1], nm[2], nm[3]); addtostatus(msgline); nmidx = 0; nm[0] = nm[1] = nm[2] = nm[3] = " "; } tok = strtok(NULL, "\n"); } /* Print any remaining names */ if (nmidx > 0) { sprintf(msgline, "%-8s %-8s %-8s %-8s\n", nm[0], nm[1], nm[2], nm[3]); addtostatus(msgline); } free(tmpstr); } if (fromline && !localmode) addtostatus(fromline); finish_status(); freestrbuffer(monmsg); if (anycountdata) sendmessage(STRBUF(countdata), NULL, BBTALK_TIMEOUT, NULL); clearstrbuffer(countdata); }
char *timespec_text(char *spec) { static char *daynames[7] = { NULL, }; static char *wkdays = NULL; static strbuffer_t *result = NULL; char *sCopy; char *p; if (result == NULL) result = newstrbuffer(0); clearstrbuffer(result); if (!daynames[0]) { /* Use strftime to get the locale-specific weekday names */ time_t now; int i; now = time(NULL); for (i=0; (i<7); i++) { char dtext[10]; struct tm *tm = localtime(&now); strftime(dtext, sizeof(dtext), "%a", tm); daynames[tm->tm_wday] = strdup(dtext); now -= 86400; } wkdays = (char *)malloc(strlen(daynames[1]) + strlen(daynames[5]) + 2); sprintf(wkdays, "%s-%s", daynames[1], daynames[5]); } p = sCopy = strdup(spec); do { char *s1, *s2, *s3, *s4, *s5; char *days = NULL, *starttime = NULL, *endtime = NULL, *columns = NULL; unsigned char *cause = NULL; char *oneday, *dtext; int daysdone = 0, firstday = 1, causelen; /* Its either DAYS:START:END or SERVICE:DAYS:START:END:CAUSE */ s1 = p; p += strcspn(p, ":"); if (*p != '\0') { *p = '\0'; p++; } s2 = p; p += strcspn(p, ":"); if (*p != '\0') { *p = '\0'; p++; } s3 = p; p += strcspn(p, ":;,"); if ((*p == ',') || (*p == ';') || (*p == '\0')) { if (*p != '\0') { *p = '\0'; p++; } days = s1; starttime = s2; endtime = s3; columns = "*"; cause = strdup("Planned downtime"); } else if (*p == ':') { *p = '\0'; p++; s4 = p; p += strcspn(p, ":"); if (*p != '\0') { *p = '\0'; p++; } s5 = p; p += strcspn(p, ",;"); if (*p != '\0') { *p = '\0'; p++; } days = s2; starttime = s3; endtime = s4; columns = s1; getescapestring(s5, &cause, &causelen); } if (!days) return ""; oneday = days; while (!daysdone) { switch (*oneday) { case '*': dtext = "All days"; break; case 'W': dtext = wkdays; break; case '0': dtext = daynames[0]; break; case '1': dtext = daynames[1]; break; case '2': dtext = daynames[2]; break; case '3': dtext = daynames[3]; break; case '4': dtext = daynames[4]; break; case '5': dtext = daynames[5]; break; case '6': dtext = daynames[6]; break; default : dtext = oneday; daysdone = firstday = 1; break; } if (!firstday) addtobuffer(result, "/"); addtobuffer(result, dtext); oneday++; firstday = 0; } addtobuffer(result, ":"); addtobuffer(result, starttime); addtobuffer(result, ":"); addtobuffer(result, endtime); addtobuffer(result, " (status:"); if (strcmp(columns, "*") == 0) addtobuffer(result, "All"); else addtobuffer(result, columns); addtobuffer(result, ")"); if (cause) { addtobuffer(result, " (cause:"); addtobuffer(result, cause); addtobuffer(result, ")"); xfree(cause); } } while (*p); xfree(sCopy); return STRBUF(result); }
void load_clientconfig(void) { static char *configfn = NULL; static void *clientconflist = NULL; FILE *fd; strbuffer_t *buf; char *sectstart; if (!configfn) { configfn = (char *)malloc(strlen(xgetenv("XYMONHOME"))+ strlen("/etc/client-local.cfg") + 1); sprintf(configfn, "%s/etc/client-local.cfg", xgetenv("XYMONHOME")); } /* First check if there were no modifications at all */ if (clientconflist) { if (!stackfmodified(clientconflist)){ dbgprintf("No files modified, skipping reload of %s\n", configfn); return; } else { stackfclist(&clientconflist); clientconflist = NULL; } } if (!clientconfigs) { clientconfigs = newstrbuffer(0); } else { xtreeDestroy(rbconfigs); clearstrbuffer(clientconfigs); } rbconfigs = xtreeNew(strcasecmp); addtobuffer(clientconfigs, "\n"); buf = newstrbuffer(0); fd = stackfopen(configfn, "r", &clientconflist); if (!fd) return; while (stackfgets(buf, NULL)) addtostrbuffer(clientconfigs, buf); stackfclose(fd); sectstart = strstr(STRBUF(clientconfigs), "\n["); while (sectstart) { char *key, *nextsect; sectstart += 2; key = sectstart; sectstart += strcspn(sectstart, "]\n"); if (*sectstart == ']') { *sectstart = '\0'; sectstart++; sectstart += strcspn(sectstart, "\n"); } nextsect = strstr(sectstart, "\n["); if (nextsect) *(nextsect+1) = '\0'; xtreeAdd(rbconfigs, key, sectstart+1); sectstart = nextsect; } freestrbuffer(buf); }
void grabdata(conn_t *conn) { int n; char buf[8192]; int pollid = 0; /* Get data from the connection socket - we know there is some */ n = read(conn->sockfd, buf, sizeof(buf)-1); if (n <= -1) { /* Read failure */ errprintf("Connection lost during read: %s\n", strerror(errno)); conn->action = C_DONE; return; } if (n > 0) { /* Got some data - store it */ buf[n] = '\0'; addtobuffer(conn->msgbuf, buf); return; } /* Done reading - process the data */ if (STRBUFLEN(conn->msgbuf) == 0) { /* No data ? We're done */ conn->action = C_DONE; return; } /* * See what kind of message this is. If it's a "pullclient" message, * save the contents of the message - this is the client configuration * that we'll return the next time a client sends us the "client" message. */ if (strncmp(STRBUF(conn->msgbuf), "pullclient", 10) == 0) { char *clientcfg; int idnum; /* Access check */ if (!oksender(serverlist, NULL, conn->caddr.sin_addr, STRBUF(conn->msgbuf))) { errprintf("Rejected pullclient request from %s\n", inet_ntoa(conn->caddr.sin_addr)); conn->action = C_DONE; return; } dbgprintf("Got pullclient request: %s\n", STRBUF(conn->msgbuf)); /* * The pollid is unique for each Xymon server. It is to allow * multiple servers to pick up the same message, for resiliance. */ idnum = atoi(STRBUF(conn->msgbuf) + 10); if ((idnum <= 0) || (idnum > 31)) { pollid = 0; } else { pollid = (1 << idnum); } conn->ctype = C_SERVER; conn->action = C_WRITING; /* Save any client config sent to us */ clientcfg = strchr(STRBUF(conn->msgbuf), '\n'); if (clientcfg) { clientcfg++; if (client_response) xfree(client_response); client_response = strdup(clientcfg); dbgprintf("Saved client response: %s\n", client_response); } } else if (strncmp(STRBUF(conn->msgbuf), "client ", 7) == 0) { /* * Got a "client" message. Return the client-response saved from * earlier, if there is any. If not, then we're done. */ conn->ctype = C_CLIENT_CLIENT; conn->action = (client_response ? C_WRITING : C_DONE); } else { /* Message from a client, but not the "client" message. So no response. */ conn->ctype = C_CLIENT_OTHER; conn->action = C_DONE; } /* * Messages we receive from clients are stored on our outbound queue. * If it's a local "client" message, respond with the queued response * from the Xymon server. Other client messages get no response. * * Server messages get our outbound queue back in response. */ if (conn->ctype != C_SERVER) { /* Messages from clients go on the outbound queue */ msgqueue_t *newq = calloc(1, sizeof(msgqueue_t)); dbgprintf("Queuing outbound message\n"); newq->tstamp = conn->tstamp; newq->msgbuf = conn->msgbuf; conn->msgbuf = NULL; if (qtail) { qtail->next = newq; qtail = newq; } else { qhead = qtail = newq; } if ((conn->ctype == C_CLIENT_CLIENT) && (conn->action == C_WRITING)) { /* Send the response back to the client */ conn->msgbuf = newstrbuffer(0); addtobuffer(conn->msgbuf, client_response); /* * Dont drop the client response data. If for some reason * the "client" request is repeated, he should still get * the right answer that we have. */ } } else { /* A server has asked us for our list of messages */ time_t now = getcurrenttime(NULL); msgqueue_t *mwalk; if (!qhead) { /* No queued messages */ conn->action = C_DONE; } else { /* Build a message of all the queued data */ clearstrbuffer(conn->msgbuf); /* Index line first */ for (mwalk = qhead; (mwalk); mwalk = mwalk->next) { if ((mwalk->sentto & pollid) == 0) { char idx[20]; sprintf(idx, "%d:%ld ", STRBUFLEN(mwalk->msgbuf), (long)(now - mwalk->tstamp)); addtobuffer(conn->msgbuf, idx); } } if (STRBUFLEN(conn->msgbuf) > 0) addtobuffer(conn->msgbuf, "\n"); /* Then the stream of messages */ for (mwalk = qhead; (mwalk); mwalk = mwalk->next) { if ((mwalk->sentto & pollid) == 0) { if (pollid) mwalk->sentto |= pollid; addtostrbuffer(conn->msgbuf, mwalk->msgbuf); } } if (STRBUFLEN(conn->msgbuf) == 0) { /* No data for this server */ conn->action = C_DONE; } } } }
void init_meta(char *metaname) { if (metabuf == NULL) metabuf = newstrbuffer(0); clearstrbuffer(metabuf); }
static char *message_text(activealerts_t *alert, recip_t *recip) { static strbuffer_t *buf = NULL; char *eoln, *bom, *p; char info[4096]; MEMDEFINE(info); if (!buf) buf = newstrbuffer(0); else clearstrbuffer(buf); if (alert->state == A_NOTIFY) { sprintf(info, "%s:%s INFO\n", alert->hostname, alert->testname); addtobuffer(buf, info); addtobuffer(buf, alert->pagemessage); MEMUNDEFINE(info); return STRBUF(buf); } switch (recip->format) { case ALERTFORM_TEXT: case ALERTFORM_PLAIN: bom = msg_data(alert->pagemessage); eoln = strchr(bom, '\n'); if (eoln) *eoln = '\0'; /* If there's a "<-- flags:.... -->" then remove it from the message */ if ((p = strstr(bom, "<!--")) != NULL) { /* Add the part of line 1 before the flags ... */ *p = '\0'; addtobuffer(buf, bom); *p = '<'; /* And the part of line 1 after the flags ... */ p = strstr(p, "-->"); if (p) addtobuffer(buf, p+3); /* And if there is more than line 1, add it as well */ if (eoln) { *eoln = '\n'; addtobuffer(buf, eoln); } } else { if (eoln) *eoln = '\n'; addtobuffer(buf, bom); } addtobuffer(buf, "\n"); if (recip->format == ALERTFORM_TEXT) { sprintf(info, "See %s%s\n", xgetenv("XYMONWEBHOST"), hostsvcurl(alert->hostname, alert->testname, 0)); addtobuffer(buf, info); } MEMUNDEFINE(info); return STRBUF(buf); case ALERTFORM_SMS: /* * Send a report containing a brief alert * and any lines that begin with a "&COLOR" */ switch (alert->state) { case A_PAGING: case A_ACKED: sprintf(info, "%s:%s %s [%d]", alert->hostname, alert->testname, colorname(alert->color), alert->cookie); break; case A_RECOVERED: sprintf(info, "%s:%s RECOVERED", alert->hostname, alert->testname); break; case A_DISABLED: sprintf(info, "%s:%s DISABLED", alert->hostname, alert->testname); break; case A_NOTIFY: sprintf(info, "%s:%s NOTICE", alert->hostname, alert->testname); break; case A_NORECIP: case A_DEAD: break; } addtobuffer(buf, info); bom = msg_data(alert->pagemessage); eoln = strchr(bom, '\n'); if (eoln) { bom = eoln; while ((bom = strstr(bom, "\n&")) != NULL) { eoln = strchr(bom+1, '\n'); if (eoln) *eoln = '\0'; if ((strncmp(bom+1, "&red", 4) == 0) || (strncmp(bom+1, "&yellow", 7) == 0)) addtobuffer(buf, bom); if (eoln) *eoln = '\n'; bom = (eoln ? eoln+1 : ""); } } MEMUNDEFINE(info); return STRBUF(buf); case ALERTFORM_SCRIPT: sprintf(info, "%s:%s %s [%d]\n", alert->hostname, alert->testname, colorname(alert->color), alert->cookie); addtobuffer(buf, info); addtobuffer(buf, msg_data(alert->pagemessage)); addtobuffer(buf, "\n"); sprintf(info, "See %s%s\n", xgetenv("XYMONWEBHOST"), hostsvcurl(alert->hostname, alert->testname, 0)); addtobuffer(buf, info); MEMUNDEFINE(info); return STRBUF(buf); case ALERTFORM_PAGER: case ALERTFORM_NONE: MEMUNDEFINE(info); return ""; } MEMUNDEFINE(info); return alert->pagemessage; }
void sendresult(void) { struct req_t *rwalk; struct oid_t *owalk; char msgline[1024]; char *currdev, *currhost; mibdef_t *mib; strbuffer_t *clientmsg = newstrbuffer(0); int havemsg = 0; int itemcount = 0; currhost = ""; for (rwalk = reqhead; (rwalk); rwalk = rwalk->next) { if (strcmp(rwalk->hostname, currhost) != 0) { /* Flush buffer */ if (havemsg) { sprintf(msgline, "\n.<!-- linecount=%d -->\n", itemcount); addtobuffer(clientmsg, msgline); sendmessage(STRBUF(clientmsg), NULL, XYMON_TIMEOUT, NULL); } clearstrbuffer(clientmsg); havemsg = 0; itemcount = 0; sprintf(msgline, "client/snmpcollect %s.snmpcollect snmp\n\n", rwalk->hostname); addtobuffer(clientmsg, msgline); } currdev = ""; for (mib = first_mib(); (mib); mib = next_mib()) { clearstrbuffer(mib->resultbuf); mib->haveresult = 0; sprintf(msgline, "\n[%s]\nInterval=%d\nActiveIP=%s\n\n", mib->mibname, atoi(xgetenv("TASKSLEEP")), rwalk->hostip[rwalk->hostipidx]); addtobuffer(mib->resultbuf, msgline); } for (owalk = rwalk->oidhead; (owalk); owalk = owalk->next) { if (strcmp(currdev, owalk->devname)) { currdev = owalk->devname; /* OK, because ->devname is permanent */ if (*owalk->devname && (*owalk->devname != '-') ) { addtobuffer(owalk->mib->resultbuf, "\n<"); addtobuffer(owalk->mib->resultbuf, owalk->devname); addtobuffer(owalk->mib->resultbuf, ">\n"); itemcount++; } } addtobuffer(owalk->mib->resultbuf, "\t"); addtobuffer(owalk->mib->resultbuf, owalk->oiddef->dsname); addtobuffer(owalk->mib->resultbuf, " = "); if (owalk->result) { int ival; unsigned int uval; switch (owalk->oiddef->conversion) { case OID_CONVERT_U32: ival = atoi(owalk->result); memcpy(&uval, &ival, sizeof(uval)); sprintf(msgline, "%u", uval); addtobuffer(owalk->mib->resultbuf, msgline); break; default: addtobuffer(owalk->mib->resultbuf, owalk->result); break; } } else addtobuffer(owalk->mib->resultbuf, "NODATA"); addtobuffer(owalk->mib->resultbuf, "\n"); owalk->mib->haveresult = 1; } for (mib = first_mib(); (mib); mib = next_mib()) { if (mib->haveresult) { addtostrbuffer(clientmsg, mib->resultbuf); havemsg = 1; } } } if (havemsg) { sendmessage(STRBUF(clientmsg), NULL, XYMON_TIMEOUT, NULL); } freestrbuffer(clientmsg); }
int main(int argc, char *argv[]) { char l[1024]; char *hset = NULL; char *p; strbuffer_t *sbuf = newstrbuffer(0); char *dayname[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" }; load_holidays(0); do { printf("$E year, $4 year, $W daynum wkday month year, Setname\n? "); fflush(stdout); if (!fgets(l, sizeof(l), stdin)) return 0; p = strchr(l, '\n'); if (p) *p = '\0'; if (hset) xfree(hset); hset = strdup(l); if (*hset == '$') { time_t t; struct tm *tm; int i; char *tok, *arg[5]; i = 0; tok = strtok(hset, " "); while (tok) { arg[i] = tok; i++; tok = strtok(NULL, " "); } if (arg[0][1] == 'E') { t = getEasterDate(atoi(arg[1]) - 1900); tm = localtime(&t); printf("Easter Sunday %04d is %02d/%02d/%04d\n", atoi(arg[1]), tm->tm_mday, tm->tm_mon+1, tm->tm_year+1900); } else if (arg[0][1] == '4') { t = get4AdventDate(atoi(arg[1]) - 1900); tm = localtime(&t); printf("4Advent %04d is %02d/%02d/%04d\n", atoi(arg[1]), tm->tm_mday, tm->tm_mon+1, tm->tm_year+1900); } else if (arg[0][1] == 'W') { struct tm wtm; memset(&wtm, 0, sizeof(wtm)); wtm.tm_mday = getnumberedweekday(atoi(arg[2]), atoi(arg[1]), atoi(arg[3]), atoi(arg[4])-1900) + 1; wtm.tm_mon = 0; wtm.tm_year = atoi(arg[4]) - 1900; wtm.tm_isdst = -1; mktime(&wtm); printf("The %d. %s in %02d/%04d is %02d/%02d/%04d\n", atoi(arg[1]), dayname[atoi(arg[2])], atoi(arg[3]), atoi(arg[4]), wtm.tm_mday, wtm.tm_mon+1, wtm.tm_year+1900); } else if (arg[0][1] == 'A') { struct tm wtm; memset(&wtm, 0, sizeof(wtm)); wtm.tm_mday = getweekdayafter(atoi(arg[2]), atoi(arg[1]), atoi(arg[3]), atoi(arg[4])-1900) + 1; wtm.tm_mon = 0; wtm.tm_year = atoi(arg[4]) - 1900; wtm.tm_isdst = -1; mktime(&wtm); printf("The %d. %s on or after %02d/%04d is %02d/%02d/%04d\n", atoi(arg[1]), dayname[atoi(arg[2])], atoi(arg[3]), atoi(arg[4]), wtm.tm_mday, wtm.tm_mon+1, wtm.tm_year+1900); } } else { int year = atoi(hset); load_holidays(year); printholidays(hset, sbuf); printf("Holidays in set: %s\n", STRBUF(sbuf)); clearstrbuffer(sbuf); } } while (1); return 0; }