char *check_downtime(char *hostname, char *testname) { namelist_t *hinfo = hostinfo(hostname); char *dtag; if (hinfo == NULL) return NULL; dtag = bbh_item(hinfo, BBH_DOWNTIME); if (dtag && *dtag) { static char *downtag = NULL; static unsigned char *cause = NULL; static int causelen = 0; char *s1, *s2, *s3, *s4, *s5, *p; char timetxt[30]; if (downtag) xfree(downtag); if (cause) xfree(cause); p = downtag = strdup(dtag); do { /* 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++; } snprintf(timetxt, sizeof(timetxt), "%s:%s:%s", s1, s2, s3); cause = strdup("Planned downtime"); s1 = "*"; } 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++; } snprintf(timetxt, sizeof(timetxt), "%s:%s:%s", s2, s3, s4); getescapestring(s5, &cause, &causelen); } if (within_sla(timetxt, 0)) { char *onesvc, *buf; if (strcmp(s1, "*") == 0) return cause; onesvc = strtok_r(s1, ",", &buf); while (onesvc) { if (strcmp(onesvc, testname) == 0) return cause; onesvc = strtok_r(NULL, ",", &buf); } } } while (*p); } return NULL; }
char *init_tcp_services(void) { static char *xymonnetsvcs = NULL; static time_t lastupdate = 0; char filename[PATH_MAX]; struct stat st; FILE *fd = NULL; strbuffer_t *inbuf; svclist_t *head, *tail, *first, *walk; char *searchstring; int svcnamebytes = 0; int svccount = 0; int i; MEMDEFINE(filename); filename[0] = '\0'; if (xgetenv("XYMONHOME")) { sprintf(filename, "%s/etc/", xgetenv("XYMONHOME")); } strcat(filename, "protocols.cfg"); if ((stat(filename, &st) == 0) && xymonnetsvcs) { /* See if we have already run and the file is unchanged - if so just pickup the result */ if (st.st_mtime == lastupdate) return xymonnetsvcs; /* File has changed - reload configuration. But clean up first so we dont leak memory. */ if (svcinfo != default_svcinfo) { for (i=0; (svcinfo[i].svcname); i++) { if (svcinfo[i].svcname) xfree(svcinfo[i].svcname); if (svcinfo[i].sendtxt) xfree(svcinfo[i].sendtxt); if (svcinfo[i].exptext) xfree(svcinfo[i].exptext); } xfree(svcinfo); svcinfo = default_svcinfo; } xfree(xymonnetsvcs); xymonnetsvcs = NULL; } if (xgetenv("XYMONNETSVCS") == NULL) { putenv("XYMONNETSVCS=smtp telnet ftp pop pop3 pop-3 ssh imap ssh1 ssh2 imap2 imap3 imap4 pop2 pop-2 nntp"); } fd = fopen(filename, "r"); if (fd == NULL) { errprintf("Cannot open TCP service-definitions file %s - using defaults\n", filename); xymonnetsvcs = strdup(xgetenv("XYMONNETSVCS")); MEMUNDEFINE(filename); return xymonnetsvcs; } lastupdate = st.st_mtime; head = tail = first = NULL; inbuf = newstrbuffer(0); initfgets(fd); while (unlimfgets(inbuf, fd)) { char *l, *eol; sanitize_input(inbuf, 1, 0); l = STRBUF(inbuf); if (*l == '[') { char *svcname; eol = strchr(l, ']'); if (eol) *eol = '\0'; l = skipwhitespace(l+1); svcname = strtok(l, "|"); first = NULL; while (svcname) { svclist_t *newitem; svccount++; svcnamebytes += (strlen(svcname) + 1); newitem = (svclist_t *) malloc(sizeof(svclist_t)); newitem->rec = (svcinfo_t *)calloc(1, sizeof(svcinfo_t)); newitem->rec->svcname = strdup(svcname); newitem->next = NULL; if (first == NULL) first = newitem; if (head == NULL) { head = tail = newitem; } else { tail->next = newitem; tail = newitem; } svcname = strtok(NULL, "|"); } } else if (strncmp(l, "send ", 5) == 0) { if (first) { getescapestring(skipwhitespace(l+4), &first->rec->sendtxt, &first->rec->sendlen); for (walk = first->next; (walk); walk = walk->next) { walk->rec->sendtxt = strdup(first->rec->sendtxt); walk->rec->sendlen = first->rec->sendlen; } } } else if (strncmp(l, "expect ", 7) == 0) { if (first) { getescapestring(skipwhitespace(l+6), &first->rec->exptext, &first->rec->explen); for (walk = first->next; (walk); walk = walk->next) { walk->rec->exptext = strdup(first->rec->exptext); walk->rec->explen = first->rec->explen; walk->rec->expofs = 0; /* HACK - not used right now */ } } } else if (strncmp(l, "options ", 8) == 0) { if (first) { char *opt; first->rec->flags = 0; l = skipwhitespace(l+7); opt = strtok(l, ","); while (opt) { if (strcmp(opt, "ssl") == 0) first->rec->flags |= TCP_SSL; else if (strcmp(opt, "banner") == 0) first->rec->flags |= TCP_GET_BANNER; else if (strcmp(opt, "telnet") == 0) first->rec->flags |= TCP_TELNET; else errprintf("Unknown option: %s\n", opt); opt = strtok(NULL, ","); } for (walk = first->next; (walk); walk = walk->next) { walk->rec->flags = first->rec->flags; } } } else if (strncmp(l, "port ", 5) == 0) { if (first) { first->rec->port = atoi(skipwhitespace(l+4)); for (walk = first->next; (walk); walk = walk->next) { walk->rec->port = first->rec->port; } } } } if (fd) fclose(fd); freestrbuffer(inbuf); /* Copy from the svclist to svcinfo table */ svcinfo = (svcinfo_t *) malloc((svccount+1) * sizeof(svcinfo_t)); for (walk=head, i=0; (walk && (i < svccount)); walk = walk->next, i++) { svcinfo[i].svcname = walk->rec->svcname; svcinfo[i].sendtxt = walk->rec->sendtxt; svcinfo[i].sendlen = walk->rec->sendlen; svcinfo[i].exptext = walk->rec->exptext; svcinfo[i].explen = walk->rec->explen; svcinfo[i].expofs = walk->rec->expofs; svcinfo[i].flags = walk->rec->flags; svcinfo[i].port = walk->rec->port; } memset(&svcinfo[svccount], 0, sizeof(svcinfo_t)); /* This should not happen */ if (walk) { errprintf("Whoa - didnt copy all services! svccount=%d, next service '%s'\n", svccount, walk->rec->svcname); } /* Free the temp. svclist list */ while (head) { /* * Note: Dont free the strings inside the records, * as they are now owned by the svcinfo records. */ walk = head; head = head->next; xfree(walk); } searchstring = strdup(xgetenv("XYMONNETSVCS")); xymonnetsvcs = (char *) malloc(strlen(xgetenv("XYMONNETSVCS")) + svcnamebytes + 1); strcpy(xymonnetsvcs, xgetenv("XYMONNETSVCS")); for (i=0; (svcinfo[i].svcname); i++) { char *p; strcpy(searchstring, xgetenv("XYMONNETSVCS")); p = strtok(searchstring, " "); while (p && (strcmp(p, svcinfo[i].svcname) != 0)) p = strtok(NULL, " "); if (p == NULL) { strcat(xymonnetsvcs, " "); strcat(xymonnetsvcs, svcinfo[i].svcname); } } xfree(searchstring); if (debug) { dump_tcp_services(); dbgprintf("XYMONNETSVCS set to : %s\n", xymonnetsvcs); } MEMUNDEFINE(filename); return xymonnetsvcs; }
/* * Split a BB test-specification with a URL and optional * post-data/expect-data/expect-type data into the URL itself * and the other elements. * Un-escape data in the post- and expect-data. * Parse the URL. */ char *decode_url(char *testspec, bburl_t *bburl) { static bburl_t bburlbuf; static urlelem_t desturlbuf, proxyurlbuf; char *inp, *p; char *urlstart, *poststart, *expstart, *proxystart; urlstart = poststart = expstart = proxystart = NULL; /* If called with no buffer, use our own static one */ if (bburl == NULL) { memset(&bburlbuf, 0, sizeof(bburl_t)); memset(&desturlbuf, 0, sizeof(urlelem_t)); memset(&proxyurlbuf, 0, sizeof(urlelem_t)); bburl = &bburlbuf; bburl->desturl = &desturlbuf; bburl->proxyurl = NULL; } else { memset(bburl, 0, sizeof(bburl_t)); bburl->desturl = (urlelem_t*) calloc(1, sizeof(urlelem_t)); bburl->proxyurl = NULL; } inp = strdup(testspec); if (strncmp(inp, "content=", 8) == 0) { bburl->testtype = BBTEST_CONTENT; urlstart = inp+8; } else if (strncmp(inp, "cont;", 5) == 0) { bburl->testtype = BBTEST_CONT; urlstart = inp+5; } else if (strncmp(inp, "cont=", 5) == 0) { bburl->testtype = BBTEST_CONT; urlstart = gethttpcolumn(inp+5, &bburl->columnname); } else if (strncmp(inp, "nocont;", 7) == 0) { bburl->testtype = BBTEST_NOCONT; urlstart = inp+7; } else if (strncmp(inp, "nocont=", 7) == 0) { bburl->testtype = BBTEST_NOCONT; urlstart = gethttpcolumn(inp+7, &bburl->columnname); } else if (strncmp(inp, "post;", 5) == 0) { bburl->testtype = BBTEST_POST; urlstart = inp+5; } else if (strncmp(inp, "post=", 5) == 0) { bburl->testtype = BBTEST_POST; urlstart = gethttpcolumn(inp+5, &bburl->columnname); } else if (strncmp(inp, "nopost;", 7) == 0) { bburl->testtype = BBTEST_NOPOST; urlstart = inp+7; } else if (strncmp(inp, "nopost=", 7) == 0) { bburl->testtype = BBTEST_NOPOST; urlstart = gethttpcolumn(inp+7, &bburl->columnname); } else if (strncmp(inp, "type;", 5) == 0) { bburl->testtype = BBTEST_TYPE; urlstart = inp+5; } else if (strncmp(inp, "type=", 5) == 0) { bburl->testtype = BBTEST_TYPE; urlstart = gethttpcolumn(inp+5, &bburl->columnname); } else { /* Plain URL test */ bburl->testtype = BBTEST_PLAIN; urlstart = inp; } switch (bburl->testtype) { case BBTEST_PLAIN: break; case BBTEST_CONT: case BBTEST_NOCONT: case BBTEST_TYPE: expstart = strchr(urlstart, ';'); if (expstart) { *expstart = '\0'; expstart++; } else { errprintf("content-check, but no content-data in '%s'\n", testspec); bburl->testtype = BBTEST_PLAIN; } break; case BBTEST_POST: case BBTEST_NOPOST: poststart = strchr(urlstart, ';'); if (poststart) { *poststart = '\0'; poststart++; expstart = strchr(poststart, ';'); if (expstart) { *expstart = '\0'; expstart++; } else { if (bburl->testtype == BBTEST_NOPOST) { errprintf("content-check, but no content-data in '%s'\n", testspec); bburl->testtype = BBTEST_PLAIN; } } } else { errprintf("post-check, but no post-data in '%s'\n", testspec); bburl->testtype = BBTEST_PLAIN; } break; } if (poststart) getescapestring(poststart, &bburl->postdata, NULL); if (expstart) getescapestring(expstart, &bburl->expdata, NULL); p = strstr(urlstart, "/http://"); if (!p) p = strstr(urlstart, "/https://"); if (p) { proxystart = urlstart; urlstart = (p+1); *p = '\0'; } parse_url(urlstart, bburl->desturl); if (proxystart) { if (bburl == &bburlbuf) { /* We use our own static buffers */ bburl->proxyurl = &proxyurlbuf; } else { /* User allocated buffers */ bburl->proxyurl = (urlelem_t *)malloc(sizeof(urlelem_t)); } parse_url(proxystart, bburl->proxyurl); } xfree(inp); return bburl->desturl->origform; }
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); }