Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
xymon/branches/4.3.28/web/appfeed.c
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
237 lines (192 sloc)
7.11 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /*----------------------------------------------------------------------------*/ | |
| /* Xymon status-log viewer CGI. */ | |
| /* */ | |
| /* This CGI provides an XML interface to the xymondboard status. Intended for */ | |
| /* use by external user interfaces, e.g. smartphones. */ | |
| /* */ | |
| /* Copyright (C) 2011 Henrik Storner <henrik@storner.dk> */ | |
| /* */ | |
| /* This program is released under the GNU General Public License (GPL), */ | |
| /* version 2. See the file "COPYING" for details. */ | |
| /* */ | |
| /*----------------------------------------------------------------------------*/ | |
| static char rcsid[] = "$Id: svcstatus.c 6765 2011-10-13 11:55:08Z storner $"; | |
| #include <limits.h> | |
| #include <stdio.h> | |
| #include <string.h> | |
| #include "libxymon.h" | |
| static char *queryfilter = NULL; | |
| static char *boardcmd = "xymondboard"; | |
| static char *fieldlist = "fields=hostname,testname,color,lastchange,logtime,cookie,acktime,ackmsg,disabletime,dismsg,line1"; | |
| static char *colorlist = "color=red,yellow,purple"; | |
| static void errormsg(char *msg) | |
| { | |
| fprintf(stderr, | |
| "Refresh: 30\nContent-type: %s\n\n<html><head><title>Invalid request</title></head>\n<body>%s</body></html>\n", | |
| xgetenv("HTMLCONTENTTYPE"), msg); | |
| } | |
| static int parse_query(void) | |
| { | |
| cgidata_t *cgidata = cgi_request(); | |
| cgidata_t *cwalk; | |
| cwalk = cgidata; | |
| while (cwalk) { | |
| if (strcasecmp(cwalk->name, "filter") == 0) { | |
| queryfilter = strdup(cwalk->value); | |
| } | |
| cwalk = cwalk->next; | |
| } | |
| if (!queryfilter) queryfilter = ""; | |
| /* See if the query includes a color filter - this overrides our default */ | |
| if ((strncmp(queryfilter, "color=", 6) == 0) || (strstr(queryfilter, " color=") != NULL)) colorlist = ""; | |
| return 0; | |
| } | |
| char *extractline(char *ptn, char **src) | |
| { | |
| char *pos = strstr(*src, ptn); | |
| char *eoln; | |
| if (pos == NULL) return NULL; | |
| eoln = strchr(pos, '\n'); | |
| if (eoln) *eoln = '\0'; | |
| if (pos == *src) | |
| *src = eoln+1; | |
| else | |
| *(pos-1) = '\0'; | |
| if (pos) pos += strlen(ptn); | |
| return pos; | |
| } | |
| int main(int argc, char **argv) | |
| { | |
| int argi; | |
| char *criticalconfig = NULL; | |
| char *envarea = NULL; | |
| char *accessfn = NULL; | |
| char *userid = getenv("REMOTE_USER"); | |
| FILE *output = stdout; | |
| char *xymondreq; | |
| sendreturn_t *sres; | |
| int xymondresult; | |
| char *log, *bol, *eoln, *endkey; | |
| 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], "--hobbit") == 0) { | |
| boardcmd = "hobbitdboard"; | |
| } | |
| else if (argnmatch(argv[argi], "--critical=")) { | |
| char *p = strchr(argv[argi], '='); | |
| criticalconfig = strdup(p+1); | |
| } | |
| else if (argnmatch(argv[argi], "--access=")) { | |
| char *p = strchr(argv[argi], '='); | |
| accessfn = strdup(p+1); | |
| } | |
| } | |
| /* Setup the query for xymond */ | |
| parse_query(); | |
| xymondreq = (char *)malloc(strlen(boardcmd) + strlen(fieldlist) + strlen(colorlist) + strlen(queryfilter) + 5); | |
| sprintf(xymondreq, "%s %s %s %s", boardcmd, fieldlist, colorlist, queryfilter); | |
| /* Get the current status */ | |
| sres = newsendreturnbuf(1, NULL); | |
| xymondresult = sendmessage(xymondreq, NULL, XYMON_TIMEOUT, sres); | |
| if (xymondresult != XYMONSEND_OK) { | |
| char *errtxt = (char *)malloc(1024 + strlen(xymondreq)); | |
| sprintf(errtxt, "Status not available: Req=%s, result=%d\n", htmlquoted(xymondreq), xymondresult); | |
| errormsg(errtxt); | |
| return 1; | |
| } | |
| else { | |
| log = getsendreturnstr(sres, 1); | |
| } | |
| freesendreturnbuf(sres); | |
| /* Load the host data (for access control) */ | |
| if (accessfn) { | |
| load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn()); | |
| load_web_access_config(accessfn); | |
| } | |
| /* Load the critical config */ | |
| if (criticalconfig) load_critconfig(criticalconfig); | |
| fprintf(output, "Content-type: text/xml\n\n"); | |
| fprintf(output, "<?xml version='1.0' encoding='ISO-8859-1'?>\n"); | |
| fprintf(output, "<StatusBoard>\n"); | |
| /* Step through the status board, one line at a time */ | |
| bol = log; | |
| while (bol && *bol) { | |
| int useit = 1; | |
| char *hostname, *testname, *color, *txt, *lastchange, *logtime, *cookie, *acktime, *ackmsg, *distime, *dismsg; | |
| eoln = strchr(bol, '\n'); if (eoln) *eoln = '\0'; | |
| if (criticalconfig) { | |
| critconf_t *cfg; | |
| /* The key for looking up items in the critical config is "hostname|testname", which we already have */ | |
| endkey = strchr(bol, '|'); if (endkey) endkey = strchr(endkey+1, '|'); | |
| *endkey = '\0'; | |
| cfg = get_critconfig(bol, CRITCONF_TIMEFILTER, NULL); | |
| *endkey = '|'; | |
| if (!cfg) useit = 0; | |
| } | |
| if (useit) { | |
| hostname = gettok(bol, "|"); | |
| testname = (hostname ? gettok(NULL, "|") : NULL); | |
| if (accessfn) useit = web_access_allowed(userid, hostname, testname, WEB_ACCESS_VIEW); | |
| } | |
| if (useit) { | |
| color = (testname ? gettok(NULL, "|") : NULL); | |
| lastchange = (color ? gettok(NULL, "|") : NULL); | |
| logtime = (lastchange ? gettok(NULL, "|") : NULL); | |
| cookie = (logtime ? gettok(NULL, "|") : NULL); | |
| acktime = (cookie ? gettok(NULL, "|") : NULL); | |
| ackmsg = (acktime ? gettok(NULL, "|") : NULL); | |
| distime = (ackmsg ? gettok(NULL, "|") : NULL); | |
| dismsg = (distime ? gettok(NULL, "|") : NULL); | |
| txt = (dismsg ? gettok(NULL, "|") : NULL); | |
| if (txt) { | |
| /* We have all data */ | |
| fprintf(output, "<ServerStatus>\n"); | |
| fprintf(output, " <Servername>%s</Servername>\n", hostname); | |
| fprintf(output, " <Type>%s</Type>\n", testname); | |
| fprintf(output, " <Status>%s</Status>\n", color); | |
| fprintf(output, " <LastChange>%s</LastChange>\n", lastchange); | |
| fprintf(output, " <LogTime>%s</LogTime>\n", logtime); | |
| fprintf(output, " <Cookie>%s</Cookie>\n", cookie); | |
| if (atoi(acktime) != 0) { | |
| char *ackedby; | |
| nldecode(ackmsg); | |
| ackedby = extractline("Acked by: ", &ackmsg); | |
| fprintf(output, " <AckTime>%s</AckTime>\n", acktime); | |
| fprintf(output, " <AckText><![CDATA[%s]]></AckText>\n", ackmsg); | |
| if (ackedby) fprintf(output, " <AckedBy><![CDATA[%s]]></AckedBy>\n", ackedby); | |
| } | |
| if (atoi(distime) != 0) { | |
| char *disabledby; | |
| nldecode(dismsg); | |
| disabledby = extractline("Disabled by: ", &dismsg); | |
| if (strncmp(dismsg, "Reason: ", 8) == 0) dismsg += 8; | |
| fprintf(output, " <DisableTime>%s</DisableTime>\n", distime); | |
| fprintf(output, " <DisableText><![CDATA[%s]]></DisableText>\n", dismsg); | |
| if (disabledby) fprintf(output, " <DisabledBy><![CDATA[%s]]></DisabledBy>\n", disabledby); | |
| } | |
| fprintf(output, " <MessageSummary><![CDATA[%s]]></MessageSummary>\n", txt); | |
| fprintf(output, " <DetailURL><![CDATA[%s]]></DetailURL>\n", hostsvcurl(hostname, testname, 0)); | |
| fprintf(output, "</ServerStatus>\n"); | |
| } | |
| } | |
| if (eoln) { | |
| *eoln = '\n'; | |
| bol = eoln+1; | |
| } | |
| else | |
| bol = NULL; | |
| } | |
| fprintf(output, "</StatusBoard>\n"); | |
| xfree(log); | |
| return 0; | |
| } | |