Exemple #1
0
static void load_hoststatus()
{
	int res;
	char msg[1024];
	sendreturn_t *sres;

	sprintf(msg, "xymondboard fields=hostname,testname,color test=%s", conncolumn);
	sres = newsendreturnbuf(1, NULL);
	res = sendmessage(msg, NULL, XYMON_TIMEOUT, sres);
	if (res == XYMONSEND_OK) connstatus = getsendreturnstr(sres, 1);

	if ((res == XYMONSEND_OK) && testcolumn) {
		sprintf(msg, "xymondboard fields=hostname,testname,color test=%s", testcolumn);
		res = sendmessage(msg, NULL, XYMON_TIMEOUT, sres);
		if (res == XYMONSEND_OK) teststatus = getsendreturnstr(sres, 1);
	}

	if (res != XYMONSEND_OK) {
		errprintf("Cannot fetch Xymon status, ignoring --no-down\n");
		connstatus = NULL;
		teststatus = NULL;
	}

	freesendreturnbuf(sres);
}
Exemple #2
0
static int prepare_fromnet(void)
{
	static char contentmd5[33] = { '\0', };
	sendreturn_t *sres;
	sendresult_t sendstat;
	char *fdata, *fhash;

	sres = newsendreturnbuf(1, NULL);
	sendstat = sendmessage("config hosts.cfg", NULL, XYMON_TIMEOUT, sres);
	if (sendstat != XYMONSEND_OK) {
		freesendreturnbuf(sres);
		errprintf("Cannot load hosts.cfg from xymond, code %d\n", sendstat);
		return -1;
	}

	fdata = getsendreturnstr(sres, 1);
	freesendreturnbuf(sres);
	fhash = md5hash(fdata);
	if (strcmp(contentmd5, fhash) == 0) {
		/* No changes */
		xfree(fdata);
		return 1;
	}

	if (contentbuffer) freestrbuffer(contentbuffer);
	contentbuffer = convertstrbuffer(fdata, 0);
	strcpy(contentmd5, fhash);

	return 0;
}
Exemple #3
0
static int getboard(int mincolor)
{
	char msg[1024];
	int i;
	sendreturn_t *sres;
	int xymondresult;


	if (!boardmaster) {
		sprintf(msg, "xymondboard acklevel=%d fields=hostname,testname,color,lastchange,logtime,validtime,acklist color=%s", critacklevel,colorname(mincolor));
		for (i=mincolor+1; (i < COL_COUNT); i++) sprintf(msg+strlen(msg), ",%s", colorname(i));

		sres = newsendreturnbuf(1, NULL);
		xymondresult = sendmessage(msg, NULL, XYMON_TIMEOUT, sres);
		if (xymondresult != XYMONSEND_OK) {
			boardmaster = "";
			freesendreturnbuf(sres);
			errormsg("Unable to fetch current status\n");
			return 1;
		}
		else {
			boardmaster = getsendreturnstr(sres, 1);
			freesendreturnbuf(sres);
		}
	}

	return 0;
}
Exemple #4
0
static int getxymondvalue(char *hostname, char *testname, char **errptr)
{
	static char *board = NULL;
	int xymondresult;
	int result = COL_CLEAR;
	char *pattern, *found, *colstr;

	if (board == NULL) {
		sendreturn_t *sres = newsendreturnbuf(1, NULL);

		xymondresult = sendmessage("xymondboard fields=hostname,testname,color", NULL, XYMON_TIMEOUT, sres);
		board = getsendreturnstr(sres, 1);

		if ((xymondresult != XYMONSEND_OK) || (board == NULL)) {
			board = "";
			*errptr += sprintf(*errptr, "Could not access xymond board, error %d\n", xymondresult);
			return COL_CLEAR;
		}

		freesendreturnbuf(sres);
	}

	pattern = (char *)malloc(1 + strlen(hostname) + 1 + strlen(testname) + 1 + 1);
	sprintf(pattern, "\n%s|%s|", hostname, testname);

	if (strncmp(board, pattern+1, strlen(pattern+1)) == 0) {
		/* The first entry in the board doesn't have the "\n" */
		found = board;
	}
	else {
		found = strstr(board, pattern);
	}

	if (found) {
		/* hostname|testname|color */
		colstr = found + strlen(pattern);
		result = parse_color(colstr);
	}

	xfree(pattern);
	return result;
}
Exemple #5
0
int validstatus(char *hname, char *tname)
{
	/* Check if a status-file is for a known host+service combination */
	static char *board = NULL;
	char buf[1024];
	char *p;
	int result = 0;


	if (!board) {
		sendreturn_t *sres;

		sres = newsendreturnbuf(1, NULL);
		if (sendmessage("hobbitdboard fields=hostname,testname", NULL, BBTALK_TIMEOUT, sres) != BB_OK) {
			errprintf("Cannot get list of host/test combinations\n");
			exit(1);
		}
		board = getsendreturnstr(sres, 1);
		freesendreturnbuf(sres);

		if (debug) {
			char fname[PATH_MAX];
			FILE *fd;

			sprintf(fname, "%s/board.dbg", xgetenv("BBTMP"));
			fd = fopen(fname, "w");
			if (fd) {
				fwrite(board, strlen(board), 1, fd);
				fclose(fd);
			}
			else {
				errprintf("Cannot open debug file %s: %s\n", fname, strerror(errno));
			}
		}
	}

	sprintf(buf, "%s|%s\n", hname, tname);
	p = strstr(board, buf);
	if (p) result = ( (p == board) || (*(p-1) == '\n'));

	return result;
}
Exemple #6
0
static void generate_wml_statuscard(host_t *host, entry_t *entry)
{
	char fn[PATH_MAX];
	FILE *fd;
	char *msg = NULL, *logbuf = NULL;
	char l[MAX_LINE_LEN], lineout[MAX_LINE_LEN];
	char *p, *outp, *nextline;
	char xymondreq[1024];
	int xymondresult;
	sendreturn_t *sres;

	sres = newsendreturnbuf(1, NULL);
	sprintf(xymondreq, "xymondlog %s.%s", host->hostname, entry->column->name);
	xymondresult = sendmessage(xymondreq, NULL, XYMON_TIMEOUT, sres);
	logbuf = getsendreturnstr(sres, 1);
	freesendreturnbuf(sres);
	if ((xymondresult != XYMONSEND_OK) || (logbuf == NULL) || (strlen(logbuf) == 0)) {
		errprintf("WML: Status not available\n");
		return;
	}

	msg = strchr(logbuf, '\n');
	if (msg) {
		msg++;
	}
	else {
		errprintf("WML: Unable to parse log data\n");
		xfree(logbuf);
		return;
	}

	nextline = msg;
	l[MAX_LINE_LEN - 1] = '\0';

	sprintf(fn, "%s/%s.%s.wml", wmldir, host->hostname, entry->column->name);
	fd = fopen(fn, "w");
	if (fd == NULL) {
		errprintf("Cannot create file %s\n", fn);
		return;
	}

	wml_header(fd, "name", 1);
	fprintf(fd, "<p align=\"center\">\n");
	fprintf(fd, "<anchor title=\"XYMON\">Host<go href=\"%s.wml\"/></anchor><br/>\n", host->hostname);
	fprintf(fd, "%s</p>\n", timestamp);
	fprintf(fd, "<p align=\"left\" mode=\"nowrap\">\n");
	fprintf(fd, "<b>%s.%s</b><br/></p><p mode=\"nowrap\">\n", host->hostname, entry->column->name);

	/*
	 * We need to parse the logfile a bit to get a decent WML
	 * card that contains the logfile. bbd does this for
	 * HTML, we need to do it ourselves for WML.
	 *
	 * Empty lines are removed.
	 * DOCTYPE lines (if any) are removed.
	 * "http://" is removed
	 * "<tr>" tags are replaced with a newline.
	 * All HTML tags are removed
	 * "&COLOR" is replaced with the shortname color
	 * "<", ">", "&", "\"" and "\'" are replaced with the coded name so they display correctly.
	 */
	while (nextline) {
		p = strchr(nextline, '\n'); if (p) *p = '\0';
		strncpy(l, nextline, (MAX_LINE_LEN - 1));
		if (p) nextline = p+1; else nextline = NULL;

		outp = lineout;

		for (p=l; (*p && isspace((int) *p)); p++) ;
		if (strlen(p) == 0) {
			/* Empty line - ignore */
		}
		else if (strstr(l, "DOCTYPE")) {
			/* DOCTYPE - ignore */
		}
		else {
			for (p=l; (*p); ) {
				if (strncmp(p, "http://", 7) == 0) {
					p += 7;
				}
				else if (strncasecmp(p, "<tr>", 4) == 0) {
					strcpy(outp, "<br/>");
					outp += 5;
					p += 4;
				}
				else if (*p == '<') {
					char *endtag, *newstarttag;

					/*
					 * Possibilities:
					 * - <html tag>	: Drop it
					 * - <          : Output the &lt; equivalent
					 * - <<<        : Handle them one '<' at a time
					 */
					endtag = strchr(p+1, '>');
					newstarttag = strchr(p+1, '<');
					if ((endtag == NULL) || (newstarttag && (newstarttag < endtag))) {
						/* Single '<', or new starttag before the end */
						strcpy(outp, "&lt;");
						outp += 4; p++;
					}
					else {
						/* Drop all html tags */
						*outp = ' '; outp++;
						p = endtag+1;
					}
				}
				else if (*p == '>') {
					strcpy(outp, "&gt;");
					outp += 4; p++;
				}
				else if (strncmp(p, "&red", 4) == 0) {
					strcpy(outp, "<b>red</b>");
					outp += 10; p += 4;
				}
				else if (strncmp(p, "&green", 6) == 0) {
					strcpy(outp, "<b>green</b>");
					outp += 12; p += 6;
				}
				else if (strncmp(p, "&purple", 7) == 0) {
					strcpy(outp, "<b>purple</b>");
					outp += 13; p += 7;
				}
				else if (strncmp(p, "&yellow", 7) == 0) {
					strcpy(outp, "<b>yellow</b>");
					outp += 13; p += 7;
				}
				else if (strncmp(p, "&clear", 6) == 0) {
					strcpy(outp, "<b>clear</b>");
					outp += 12; p += 6;
				}
				else if (strncmp(p, "&blue", 5) == 0) {
					strcpy(outp, "<b>blue</b>");
					outp += 11; p += 5;
				}
				else if (*p == '&') {
					strcpy(outp, "&amp;");
					outp += 5; p++;
				}
				else if (*p == '\'') {
					strcpy(outp, "&apos;");
					outp += 6; p++;
				}
				else if (*p == '\"') {
					strcpy(outp, "&quot;");
					outp += 6; p++;
				}
				else {
					*outp = *p;
					outp++; p++; 
				}
			}
		}
		*outp = '\0';
		if (strlen(lineout)) fprintf(fd, "%s\n<br/>\n", lineout);
	}
	fprintf(fd, "<br/> </p> </card> </wml>\n");

	fclose(fd);
	if (logbuf) xfree(logbuf);
}
Exemple #7
0
int main(int argc, char *argv[])
{
    int argi, hosti, testi;
    char *pagepattern = NULL, *hostpattern = NULL;
    char *envarea = NULL, *cookie = NULL, *nexthost;
    char *hobbitcmd, *procscmd, *svcscmd;
    int alertcolors, alertinterval;
    char configfn[PATH_MAX];
    char *respbuf = NULL, *procsbuf = NULL, *svcsbuf = NULL;
    hostlist_t *hwalk;
    htnames_t *twalk;
    hostlist_t **allhosts = NULL;
    htnames_t **alltests = NULL;
    int hostcount = 0, maxtests = 0;
    time_t now = getcurrenttime(NULL);
    sendreturn_t *sres;

    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 (argnmatch(argv[argi], "--delimiter=")) {
            char *p = strchr(argv[argi], '=');
            coldelim = strdup(p+1);
        }
        else if (strcmp(argv[argi], "--critical") == 0) {
            nkonly = 1;
        }
        else if (strcmp(argv[argi], "--old-nk-config") == 0) {
            newnkconfig = 0;
        }
    }

    redirect_cgilog("hobbit-confreport");

    load_hostnames(xgetenv("BBHOSTS"), NULL, get_fqdn());
    load_nkconfig(NULL);

    /* Setup the filter we use for the report */
    cookie = get_cookie("pagepath");
    if (cookie && *cookie) pagepattern = strdup(cookie);
    cookie = get_cookie("host");
    if (cookie && *cookie) hostpattern = strdup(cookie);

    /* Fetch the list of host+test statuses we currently know about */
    if (pagepattern) {
        hobbitcmd = (char *)malloc(2*strlen(pagepattern) + 1024);
        procscmd = (char *)malloc(2*strlen(pagepattern) + 1024);
        svcscmd = (char *)malloc(2*strlen(pagepattern) + 1024);

        sprintf(hobbitcmd, "hobbitdboard page=^%s$|^%s/.+ fields=hostname,testname",
                pagepattern, pagepattern);
        sprintf(procscmd,  "hobbitdboard page=^%s$|^%s/.+ test=procs fields=hostname,msg",
                pagepattern, pagepattern);
        sprintf(svcscmd,   "hobbitdboard page=^%s$|^%s/.+ test=svcs fields=hostname,msg",
                pagepattern, pagepattern);
    }
    else if (hostpattern) {
        hobbitcmd = (char *)malloc(strlen(hostpattern) + 1024);
        procscmd = (char *)malloc(strlen(hostpattern) + 1024);
        svcscmd = (char *)malloc(strlen(hostpattern) + 1024);

        sprintf(hobbitcmd, "hobbitdboard host=^%s$ fields=hostname,testname", hostpattern);
        sprintf(procscmd,  "hobbitdboard host=^%s$ test=procs fields=hostname,msg", hostpattern);
        sprintf(svcscmd,   "hobbitdboard host=^%s$ test=svcs fields=hostname,msg", hostpattern);
    }
    else {
        hobbitcmd = (char *)malloc(1024);
        procscmd = (char *)malloc(1024);
        svcscmd = (char *)malloc(1024);

        sprintf(hobbitcmd, "hobbitdboard fields=hostname,testname");
        sprintf(procscmd,  "hobbitdboard test=procs fields=hostname,msg");
        sprintf(svcscmd,   "hobbitdboard test=svcs fields=hostname,msg");
    }

    sres = newsendreturnbuf(1, NULL);

    if (sendmessage(hobbitcmd, NULL, BBTALK_TIMEOUT, sres) != BB_OK) {
        errormsg("Cannot contact the Hobbit server\n");
        return 1;
    }
    respbuf = getsendreturnstr(sres, 1);
    if (sendmessage(procscmd, NULL, BBTALK_TIMEOUT, sres) != BB_OK) {
        errormsg("Cannot contact the Hobbit server\n");
        return 1;
    }
    procsbuf = getsendreturnstr(sres, 1);
    if (sendmessage(svcscmd, NULL, BBTALK_TIMEOUT, sres) != BB_OK) {
        errormsg("Cannot contact the Hobbit server\n");
        return 1;
    }
    svcsbuf = getsendreturnstr(sres, 1);

    freesendreturnbuf(sres);

    if (!respbuf) {
        errormsg("Unable to find host information\n");
        return 1;
    }

    /* Parse it into a usable list */
    nexthost = respbuf;
    do {
        char *hname, *tname, *eoln;
        int wanted = 1;

        eoln = strchr(nexthost, '\n');
        if (eoln) *eoln = '\0';
        hname = nexthost;
        tname = strchr(nexthost, '|');
        if (tname) {
            *tname = '\0';
            tname++;
        }

        if (nkonly) {
            void *hinfo = hostinfo(hname);
            char *nkalerts = bbh_item(hinfo, BBH_NK);

            if (newnkconfig) {
                if (strcmp(nkval(hname, tname, nkalerts), "No") == 0 ) wanted = 0;
            } else {
                if (!nkalerts) wanted = 0;
            }
        }

        if (wanted && hname && tname && strcmp(hname, "summary") && strcmp(tname, xgetenv("INFOCOLUMN")) && strcmp(tname, xgetenv("TRENDSCOLUMN"))) {
            htnames_t *newitem = (htnames_t *)malloc(sizeof(htnames_t));

            for (hwalk = hosthead; (hwalk && strcmp(hwalk->hostname, hname)); hwalk = hwalk->next);
            if (!hwalk) {
                hwalk = (hostlist_t *)calloc(1, sizeof(hostlist_t));
                hwalk->hostname = strdup(hname);
                hwalk->procs = get_proclist(hname, procsbuf);
                hwalk->svcs  = get_proclist(hname, svcsbuf);
                hwalk->next = hosthead;
                hosthead = hwalk;
                hostcount++;
            }

            newitem->name = strdup(tname);
            newitem->next = hwalk->tests;
            hwalk->tests = newitem;
            hwalk->testcount++;
        }

        if (eoln) {
            nexthost = eoln+1;
            if (*nexthost == '\0') nexthost = NULL;
        }
    } while (nexthost);

    allhosts = (hostlist_t **) malloc(hostcount * sizeof(hostlist_t *));
    for (hwalk = hosthead, hosti=0; (hwalk); hwalk = hwalk->next, hosti++) {
        allhosts[hosti] = hwalk;
        if (hwalk->testcount > maxtests) maxtests = hwalk->testcount;
    }
    alltests = (htnames_t **) malloc(maxtests * sizeof(htnames_t *));
    qsort(&allhosts[0], hostcount, sizeof(hostlist_t **), host_compare);

    /* Get the static info */
    load_all_links();
    init_tcp_services();
    pingcolumn = xgetenv("PINGCOLUMN");
    pingplus = (char *)malloc(strlen(pingcolumn) + 2);
    sprintf(pingplus, "%s=", pingcolumn);

    /* Load alert config */
    alertcolors = colorset(xgetenv("ALERTCOLORS"), ((1 << COL_GREEN) | (1 << COL_BLUE)));
    alertinterval = 60*atoi(xgetenv("ALERTREPEAT"));
    sprintf(configfn, "%s/etc/hobbit-alerts.cfg", xgetenv("BBHOME"));
    load_alertconfig(configfn, alertcolors, alertinterval);
    load_columndocs();


    printf("Content-Type: %s\n\n", xgetenv("HTMLCONTENTTYPE"));
    sethostenv("", "", "", colorname(COL_BLUE), NULL);
    headfoot(stdout, "confreport", "", "header", COL_BLUE);

    fprintf(stdout, "<table width=\"100%%\" border=0>\n");
    fprintf(stdout, "<tr><th align=center colspan=2><font size=\"+2\">Hobbit configuration Report</font></th></tr>\n");
    fprintf(stdout, "<tr><th valign=top align=left>Date</th><td>%s</td></tr>\n", ctime(&now));
    fprintf(stdout, "<tr><th valign=top align=left>%d hosts included</th><td>\n", hostcount);
    for (hosti=0; (hosti < hostcount); hosti++) {
        fprintf(stdout, "%s ", allhosts[hosti]->hostname);
    }
    fprintf(stdout, "</td></tr>\n");
    if (nkonly) {
        fprintf(stdout, "<tr><th valign=top align=left>Filter</th><td>Only data for the &quot;Critical Systems&quot; view reported</td></tr>\n");
    }
    fprintf(stdout, "</table>\n");

    headfoot(stdout, "confreport", "", "front", COL_BLUE);

    for (hosti=0; (hosti < hostcount); hosti++) {
        for (twalk = allhosts[hosti]->tests, testi = 0; (twalk); twalk = twalk->next, testi++) {
            alltests[testi] = twalk;
        }
        qsort(&alltests[0], allhosts[hosti]->testcount, sizeof(htnames_t **), test_compare);

        print_host(allhosts[hosti], alltests, allhosts[hosti]->testcount);
    }

    headfoot(stdout, "confreport", "", "back", COL_BLUE);
    print_columndocs();

    headfoot(stdout, "confreport", "", "footer", COL_BLUE);

    return 0;
}
Exemple #8
0
static void count_duration(time_t fromtime, time_t totime,
			   pcre *pageregexp, pcre *expageregexp,
			   pcre *hostregexp, pcre *exhostregexp,
			   pcre *testregexp, pcre *extestregexp,
			   int ignoredialups, f_hostcheck hostcheck,
			   event_t *eventhead, countlist_t **hostcounthead, countlist_t **svccounthead)
{
	void *hwalk;
	elist_t *lwalk;
	event_t *ewalk;
	ed_t *ed;
	sendreturn_t *bdata;

	/*
	 * Restructure the event-list so we have a tree instead:
	 *
	 *      HostRecord
	 *      |  *Data ---->  EventList
	 *      |               |  *Service
	 *      |               |  *EventHead --> Event --> Event --> Event
	 *      |               |  *EventTail --------------------------^
	 *      |               |
	 *      |               v
	 *      |
	 *      v
	 *
	 */
	for (ewalk = eventhead; (ewalk); ewalk = ewalk->next) {
		lwalk = (elist_t *)xmh_item(ewalk->host, XMH_DATA);
		while (lwalk && (lwalk->svc != ewalk->service)) lwalk = lwalk->next;
		if (lwalk == NULL) {
			lwalk = (elist_t *)calloc(1, sizeof(elist_t));
			lwalk->svc = ewalk->service;
			lwalk->next = (elist_t *)xmh_item(ewalk->host, XMH_DATA);
			xmh_set_item(ewalk->host, XMH_DATA, (void *)lwalk);
		}

		ed = (ed_t *)calloc(1, sizeof(ed_t));
		ed->event = ewalk;
		ed->next = lwalk->head;
		if (lwalk->head == NULL) lwalk->tail = ed;
		lwalk->head = ed;
	}

	if (debug) {
		printf("\n\nEventtree before fixups\n\n");
		dump_eventtree();
	}
	
	/* 
	 * Next, we must add a pseudo record for the current state.
	 * This is for those statuses that haven't changed since the 
	 * start of our data-collection period - they won't have any events
	 * so we cannot tell what color they are. By grabbing the current
	 * color we can add a pseudo-event that lets us determine what the 
	 * color has been since the start of the event-period.
	 */
	bdata = newsendreturnbuf(1, NULL);
	if (sendmessage("xymondboard fields=hostname,testname,color,lastchange", NULL, XYMON_TIMEOUT, bdata) == XYMONSEND_OK) {
		char *bol, *eol;
		char *hname, *tname;
		int color;
		time_t lastchange;
		void *hrec;
		htnames_t *srec;
		char *icname = xgetenv("INFOCOLUMN");
		char *tcname = xgetenv("TRENDSCOLUMN");

		bol = getsendreturnstr(bdata, 0);
		while (bol) {
			eol = strchr(bol, '\n'); if (eol) *eol = '\0';
			hname = strtok(bol, "|");
			tname = (hname ? strtok(NULL, "|") : NULL);
			color = (tname ? parse_color(strtok(NULL, "|")) : -1);
			lastchange = ((color != -1) ? atol(strtok(NULL, "\n")) : totime+1);

			if (hname && tname && (color != -1) && (strcmp(tname, icname) != 0) && (strcmp(tname, tcname) != 0)) {
				hrec = hostinfo(hname);
				srec = getname(tname, 1);

				if (eventfilter(hrec, tname, 
						pageregexp, expageregexp, 
						hostregexp, exhostregexp,
						testregexp, extestregexp,
						ignoredialups, hostcheck) == 0) goto nextrecord;

				lwalk = (elist_t *)xmh_item(hrec, XMH_DATA);
				while (lwalk && (lwalk->svc != srec)) lwalk = lwalk->next;
				if (lwalk == NULL) {
					lwalk = (elist_t *)calloc(1, sizeof(elist_t));
					lwalk->svc = srec;
					lwalk->next = (elist_t *)xmh_item(hrec, XMH_DATA);
					xmh_set_item(hrec, XMH_DATA, (void *)lwalk);
				}

				/* See if we already have an event past the "totime" value */
				if (lwalk->head) {
					ed = lwalk->head;
					while (ed && (ed->event->eventtime < totime)) ed = ed->next;

					if (ed) {
						ed->next = NULL;
						lwalk->tail = ed;
					}
					else {
						ed = (ed_t *)calloc(1, sizeof(ed_t));
						ed->event = (event_t *)calloc(1, sizeof(event_t));
						lwalk->tail->next = ed;

						ed->event->host = hrec;
						ed->event->service = srec;
						ed->event->eventtime = totime;
						ed->event->changetime = lwalk->tail->event->eventtime;
						ed->event->duration = (totime - lwalk->tail->event->eventtime);
						ed->event->newcolor = -1;
						ed->event->oldcolor = lwalk->tail->event->newcolor;
						ed->event->next = NULL;
						ed->next = NULL;

						lwalk->tail = ed;
					}
				}
				else if (lastchange < totime) {
					ed = (ed_t *)calloc(1, sizeof(ed_t));
					ed->event = (event_t *)calloc(1, sizeof(event_t));
					ed->event->host = hrec;
					ed->event->service = srec;
					ed->event->eventtime = totime;
					ed->event->changetime = (lwalk->tail ? lwalk->tail->event->eventtime : fromtime);
					ed->event->duration = (totime - ed->event->changetime);
					ed->event->newcolor = color;
					ed->event->oldcolor = (lwalk->tail ? lwalk->tail->event->newcolor : color);
					ed->event->next = NULL;
					ed->next = NULL;

					lwalk->head = lwalk->tail = ed;
				}
			}

nextrecord:
			bol = (eol ? eol+1 : NULL);
		}

		freesendreturnbuf(bdata);
	}
	else {
		errprintf("Cannot get the current state\n");
		freesendreturnbuf(bdata);
		return;
	}

	if (debug) {
		printf("\n\nEventtree after pseudo-events\n\n");
		dump_eventtree();
	}
	
	/* 
	 * Fixup the beginning-time (and duration) of the first events recorded.
	 * This is to handle events that begin BEFORE our event-logging period.
	 * Fixup the end-time (and duration) of the last events recorded.
	 * This is to handle events that end AFTER our event-logging period.
	 */
	for (hwalk = first_host(); (hwalk); hwalk = next_host(hwalk, 0)) {
		elist_t *lwalk;
		event_t *erec;
		ed_t *ewalk;

		lwalk = (elist_t *)xmh_item(hwalk, XMH_DATA); 
		while (lwalk) {
			if (lwalk->head) {
				erec = lwalk->head->event;
				if (erec->changetime > totime) {
					/* First event is after our start-time. Drop the events */
					lwalk->head = lwalk->tail = NULL;
				}
				else if (erec->changetime < fromtime) {
					/* First event is before our start-time. Adjust to starttime. */
					erec->changetime = fromtime;
					erec->duration = (erec->eventtime - fromtime);
				}

				ewalk = lwalk->head;
				while (ewalk && (ewalk->event->eventtime < totime)) ewalk = ewalk->next;
				if (ewalk) {
					lwalk->tail = ewalk;
					lwalk->tail->next = 0;
				}

				if (lwalk->tail) {
					erec = lwalk->tail->event;
					if (erec->eventtime > totime) {
						/* Last event is after our end-time. Adjust to end-time */
						erec->eventtime = totime;
						erec->duration = (totime - erec->changetime);
					}
				}
			}

			lwalk = lwalk->next;
		}
	}

	if (debug) {
		printf("\n\nEventtree after fixups\n\n");
		dump_eventtree();
	}

	for (hwalk = first_host(); (hwalk); hwalk = next_host(hwalk, 0)) {
		countlist_t *hrec, *srec;

		hrec = (countlist_t *)malloc(sizeof(countlist_t));
		hrec->src = hwalk;
		hrec->total = 0;
		hrec->next = *hostcounthead;
		*hostcounthead = hrec;

		lwalk = (elist_t *)xmh_item(hwalk, XMH_DATA);
		while (lwalk) {
			for (srec = *svccounthead; (srec && (srec->src != (void *)lwalk->svc)); srec = srec->next) ;
			if (!srec) {
				srec = (countlist_t *)malloc(sizeof(countlist_t));
				srec->src = (void *)lwalk->svc;
				srec->total = 0;
				srec->next = *svccounthead;
				*svccounthead = srec;
			}

			if (lwalk->head) {
				ed_t *ewalk = lwalk->head;

				while (ewalk) {
					if (ewalk->event->oldcolor >= COL_YELLOW) {
						hrec->total += ewalk->event->duration;
						srec->total += ewalk->event->duration;
					}
					ewalk = ewalk->next;
				}
			}

			lwalk = lwalk->next;
		}
	}

	if (debug) dump_countlists(*hostcounthead, *svccounthead);
}
void load_checkpoint(char *filename)
{
	char *subfn;
	FILE *fd;
	strbuffer_t *inbuf;
	char statuscmd[1024];
	char *statusbuf = NULL;
	sendreturn_t *sres;

	fd = fopen(filename, "r");
	if (fd == NULL) return;

	sprintf(statuscmd, "xymondboard color=%s fields=hostname,testname,color", xgetenv("ALERTCOLORS"));
	sres = newsendreturnbuf(1, NULL);
	sendmessage(statuscmd, NULL, XYMON_TIMEOUT, sres);
	statusbuf = getsendreturnstr(sres, 1);
	freesendreturnbuf(sres);

	initfgets(fd);
	inbuf = newstrbuffer(0);
	while (unlimfgets(inbuf, fd)) {
		char *item[20], *p;
		int i;

		sanitize_input(inbuf, 0, 0);

		i = 0; p = gettok(STRBUF(inbuf), "|");
		while (p && (i < 20)) {
			item[i++] = p;
			p = gettok(NULL, "|");
		}

		if (i == 9) {
			/* There was no ack message */
			item[i++] = "";
		}

		if (i > 9) {
			char *valid = NULL;

			activealerts_t *newalert = (activealerts_t *)calloc(1, sizeof(activealerts_t));
			newalert->hostname = find_name(hostnames, item[0]);
			newalert->testname = find_name(testnames, item[1]);
			newalert->location = find_name(locations, item[2]);
			newalert->ip = strdup(item[3]);
			newalert->color = newalert->maxcolor = parse_color(item[4]);
			newalert->eventstart = (time_t) atoi(item[5]);
			newalert->nextalerttime = (time_t) atoi(item[6]);
			newalert->state = A_PAGING;

			if (statusbuf) {
				char *key;

				key = (char *)malloc(strlen(newalert->hostname) + strlen(newalert->testname) + 100);
				sprintf(key, "\n%s|%s|%s\n", newalert->hostname, newalert->testname, colorname(newalert->color));
				valid = strstr(statusbuf, key);
				if (!valid && (strncmp(statusbuf, key+1, strlen(key+1)) == 0)) valid = statusbuf;
				xfree(key);
			}
			if (!valid) {
				errprintf("Stale alert for %s:%s dropped\n", newalert->hostname, newalert->testname);
				xfree(newalert);
				continue;
			}

			while (strcmp(item[7], statename[newalert->state]) && (newalert->state < A_DEAD)) 
				newalert->state++;
			/* Config might have changed while we were down */
			if (newalert->state == A_NORECIP) newalert->state = A_PAGING;
			newalert->pagemessage = newalert->ackmessage = NULL;
			if (strlen(item[8])) {
				nldecode(item[8]);
				newalert->pagemessage = strdup(item[8]);
			}
			if (strlen(item[9])) {
				nldecode(item[9]);
				newalert->ackmessage = strdup(item[9]);
			}
			add_active(newalert->hostname, newalert);
		}
	}
	fclose(fd);
	freestrbuffer(inbuf);

	subfn = (char *)malloc(strlen(filename)+5);
	sprintf(subfn, "%s.sub", filename);
	load_state(subfn, statusbuf);
	xfree(subfn);
	if (statusbuf) xfree(statusbuf);
}
Exemple #10
0
int main(int argc, char *argv[])
{
	char *envarea = NULL;
	char *server = NULL;
	char *cookie, *pagefilter = "";
	char *filter = NULL;
	char *heading = NULL;
	int  showcolors = 1;
	int  showcolumn = 0;
	int  addlink = 0;
	int  allhosts = 0;
	int  summary = 0;
	int  embedded = 0;
	char *req, *board, *l;
	int argi, res;
	sendreturn_t *sres;

	init_timestamp();
	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 ( argnmatch(argv[argi], "--column=") || argnmatch(argv[argi], "--test=")) {
			char *p = strchr(argv[argi], '=');
			int needed;
			
			needed = 10 + strlen(p); if (filter) needed += strlen(filter);
			filter = (char *)(filter ? realloc(filter, needed) : calloc(1, needed));
			sprintf(filter + strlen(filter), " test=%s", p+1);

			if (!heading) {
				heading = (char *)malloc(1024 + strlen(p) + strlen(timestamp));
				sprintf(heading, "%s report on %s", p+1, timestamp);
			}
		}
		else if (argnmatch(argv[argi], "--filter=")) {
			char *p = strchr(argv[argi], '=');
			int needed;
			
			needed = 10 + strlen(p); if (filter) needed += strlen(filter);
			filter = (char *)(filter ? realloc(filter, needed) : calloc(1, needed));
			sprintf(filter + strlen(filter), " %s", p+1);
		}
		else if (argnmatch(argv[argi], "--heading=")) {
			char *p = strchr(argv[argi], '=');

			heading = strdup(p+1);
		}
		else if (strcmp(argv[argi], "--show-column") == 0) {
			showcolumn = 1;
		}
		else if (strcmp(argv[argi], "--show-test") == 0) {
			showcolumn = 1;
		}
		else if (strcmp(argv[argi], "--show-colors") == 0) {
			showcolors = 1;
		}
		else if (strcmp(argv[argi], "--show-summary") == 0) {
			summary = 1;
		}
		else if (strcmp(argv[argi], "--show-message") == 0) {
			summary = 0;
		}
		else if (strcmp(argv[argi], "--link") == 0) {
			addlink = 1;
		}
		else if (strcmp(argv[argi], "--no-colors") == 0) {
			showcolors = 0;
		}
		else if (strcmp(argv[argi], "--all") == 0) {
			allhosts = 1;
		}
		else if (strcmp(argv[argi], "--embedded") == 0) {
			embedded = 1;
		}
	}

	if (!allhosts) {
      		/* Setup the filter we use for the report */
		cookie = get_cookie("pagepath");
		if (cookie && *cookie) {
			pcre *dummy;
			char *re = (char *)malloc(8 + 2*strlen(cookie));

			sprintf(re, "^%s$|^%s/.+", cookie, cookie);
			dummy = compileregex(re);
			if (dummy)  {
				freeregex(dummy);
				pagefilter = malloc(10 + strlen(re));
				sprintf(pagefilter, "page=%s", re);
			}
		}
	}

	sres = newsendreturnbuf(1, NULL);
	req = malloc(1024 + strlen(pagefilter) + strlen(filter));
	sprintf(req, "xymondboard fields=hostname,testname,color,msg %s %s",
		pagefilter, filter);
	res = sendmessage(req, server, XYMON_TIMEOUT, sres);
	board = getsendreturnstr(sres, 1);
	freesendreturnbuf(sres);

	if (res != XYMONSEND_OK) return 1;

	if (!embedded) {
		printf("Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE"));

		printf("<html><head><title>%s</title></head>\n", htmlquoted(heading));
		printf("<body>");
		printf("<table border=1 cellpadding=5><tr><th>%s</th><th align=left>Status</th></tr>\n",
		       (showcolumn ? "Host/Column" : "Host"));
	}

	l = board;
	while (l && *l) {
		char *hostname, *testname = NULL, *colorstr = NULL, *msg = NULL, *p;
		char *eoln = strchr(l, '\n');
		if (eoln) *eoln = '\0';

		hostname = l;
		p = strchr(l, '|'); if (p) { *p = '\0'; l = testname = p+1; }
		p = strchr(l, '|'); if (p) { *p = '\0'; l = colorstr = p+1; }
		p = strchr(l, '|'); if (p) { *p = '\0'; l = msg = p+1; }
		if (hostname && testname && colorstr && msg) {
			char *msgeol;

			nldecode(msg);
			msgeol = strchr(msg, '\n');
			if (msgeol) {
				/* Skip the first status line */
				msg = msgeol + 1;
			}
			printf("<tr><td align=left valign=top><b>");

			if (addlink) 
				printf("<a href=\"%s\">%s</a>", hostsvcurl(hostname, xgetenv("INFOCOLUMN"), 1), htmlquoted(hostname));
			else 
				printf("%s", htmlquoted(hostname));

			if (showcolumn) {
				printf("<br>");
				if (addlink) 
					printf("<a href=\"%s\">%s</a>", hostsvcurl(hostname, testname, 1), htmlquoted(testname));
				else
					printf("%s", htmlquoted(testname));
			}

			if (showcolors) printf("&nbsp;-&nbsp;%s", colorstr);

			printf("</b></td>\n");

			printf("<td><pre>\n");

			if (summary) {
				int firstline = 1;
				char *bol, *eol;

				bol = msg;
				while (bol) {
					eol = strchr(bol, '\n'); if (eol) *eol = '\0';

					if (firstline) {
						if (!isspace((int)*bol)) {
							printf("%s\n", bol);
							firstline = 0;
						}
					}
					else if ((*bol == '&') && (strncmp(bol, "&green", 6) != 0)) {
						printf("%s\n", bol);
					}

					bol = (eol ? eol+1 : NULL);
				}
			}
			else {
				printf("%s", msg);
			}

			printf("</pre></td></tr>\n");
		}

		if (eoln) l = eoln+1; else l = NULL;
	}

	if (!embedded) printf("</table></body></html>\n");

	return 0;
}
Exemple #11
0
int main(int argc, char *argv[])
{
	int argi;
	char *envarea = NULL;
	char *hffile = "ghosts";
	int bgcolor = COL_BLUE;
	char *ghosts = NULL;
	sendreturn_t *sres;

	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 (argnmatch(argv[argi], "--hffile=")) {
			char *p = strchr(argv[argi], '=');
			hffile = strdup(p+1);
		}
	}

	load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn());
	parse_query();

	switch (outform) {
	  case O_HTML:
		fprintf(stdout, "Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE"));
		headfoot(stdout, hffile, "", "header", bgcolor);
		break;
	  case O_TXT:
		fprintf(stdout, "Content-type: text/plain\n\n");
		break;
	}

	sres = newsendreturnbuf(1, NULL);

	if (sendmessage("ghostlist", NULL, XYMON_TIMEOUT, sres) == XYMONSEND_OK) {
		char *bol, *eoln, *name, *sender, *timestr;
		time_t tstamp, now;
		int count, idx;
		ghost_t *ghosttable;

		ghosts = getsendreturnstr(sres, 1);

		/* Count the number of lines */
		for (bol = ghosts, count=0; (bol); bol = strchr(bol, '\n')) {
			if (*bol == '\n') bol++;
			count++;
		}
		ghosttable = (ghost_t *)calloc(count+1, sizeof(ghost_t));

		idx = count = 0;
		tstamp = now = getcurrenttime(NULL);
		bol = ghosts;
		while (bol) {
			name = sender = timestr = NULL;

			eoln = strchr(bol, '\n'); if (eoln) *eoln = '\0';
			name = strtok(bol, "|");
			if (name) sender = strtok(NULL, "|");
			if (sender) timestr = strtok(NULL, "|");

			if (timestr) tstamp = atol(timestr);

			if (name && sender && timestr && (tstamp > (now - maxage))) {
				int i1, i2, i3, i4;

				sscanf(sender, "%d.%d.%d.%d", &i1, &i2, &i3, &i4);
				ghosttable[idx].sender = sender;
				ghosttable[idx].senderval = (i1 << 24) + (i2 << 16) + (i3 << 8) + i4;
				ghosttable[idx].name = name;
				ghosttable[idx].tstamp = tstamp;
				find_candidate(&ghosttable[idx]);
				idx++; count++;
			}

			if (eoln) eoln++;
			bol = eoln;
		}

		switch (sorttype) {
		  case S_NAME:
			qsort(&ghosttable[0], count, sizeof(ghost_t), hostname_compare);
			break;

		  case S_SENDER:
			qsort(&ghosttable[0], count, sizeof(ghost_t), sender_compare);
			break;

		  case S_TIME:
			qsort(&ghosttable[0], count, sizeof(ghost_t), time_compare);
			break;
		}

		if (outform == O_HTML) {
			fprintf(stdout, "<table align=center>\n");
			fprintf(stdout, "<tr>");
			fprintf(stdout, "<th align=left><a href=\"ghostlist.sh?SORT=name&MAXAGE=%d\">Hostname</a></th>", maxage);
			fprintf(stdout, "<th align=left><a href=\"ghostlist.sh?SORT=sender&MAXAGE=%d\">Sent from</a></th>", maxage);
			fprintf(stdout, "<th align=left>Candidate</th>");
			fprintf(stdout, "<th align=right><a href=\"ghostlist.sh?SORT=time&MAXAGE=%d\">Report age</a></th>", maxage);
			fprintf(stdout, "</tr>\n");
		}

		for (idx = 0; (idx < count); idx++) {
			if (!ghosttable[idx].name) continue;
			if (!ghosttable[idx].sender) continue;

			switch (outform) {
			  case O_HTML:
				fprintf(stdout, "<tr><td align=left>%s</td><td align=left>%s</td>",
					ghosttable[idx].name, 
					ghosttable[idx].sender);

				if (ghosttable[idx].candidate) {
					fprintf(stdout, "<td align=left><a href=\"%s\">%s</a></td>",
						hostsvcurl(xmh_item(ghosttable[idx].candidate, XMH_HOSTNAME), xgetenv("INFOCOLUMN"), 1),
						xmh_item(ghosttable[idx].candidate, XMH_HOSTNAME));
				}
				else {
					fprintf(stdout, "<td>&nbsp;</td>");
				}

				fprintf(stdout, "<td align=right>%ld:%02ld</td></tr>\n",
					(now - ghosttable[idx].tstamp)/60, (now - ghosttable[idx].tstamp)%60);
				break;

			  case O_TXT:
				fprintf(stdout, "%s\t\t%s\n", ghosttable[idx].sender, ghosttable[idx].name);
				break;
			}
		}

		if (outform == O_HTML) {
			fprintf(stdout, "</table>\n");
			fprintf(stdout, "<br><br><center><a href=\"ghostlist.sh?SORT=%s&MAXAGE=%d&TEXT\">Text report</a></center>\n", htmlquoted(sortstring), maxage);
		}
	}
	else
		fprintf(stdout, "<h3><center>Failed to retrieve ghostlist from server</center></h3>\n");

	freesendreturnbuf(sres);

	if (outform == O_HTML) {
		headfoot(stdout, hffile, "", "footer", bgcolor);
	}

	return 0;
}
Exemple #12
0
int loadstatus(int maxprio, time_t maxage, int mincolor, int wantacked)
{
	int xymondresult;
	char *board = NULL;
	char *bol, *eol;
	time_t now;
	char msg[1024];
	int i;
	sendreturn_t *sres;

	sprintf(msg, "xymondboard acklevel=%d fields=hostname,testname,color,lastchange,logtime,validtime,acklist color=%s", critacklevel,colorname(mincolor));
	for (i=mincolor+1; (i < COL_COUNT); i++) sprintf(msg+strlen(msg), ",%s", colorname(i));

	sres = newsendreturnbuf(1, NULL);
	xymondresult = sendmessage(msg, NULL, XYMON_TIMEOUT, sres);
	if (xymondresult != XYMONSEND_OK) {
		freesendreturnbuf(sres);
		errormsg("Unable to fetch current status\n");
		return 1;
	}
	else {
		board = getsendreturnstr(sres, 1);
		freesendreturnbuf(sres);
	}

	now = getcurrenttime(NULL);
	rbstate = rbtNew(name_compare);

	bol = board;
	while (bol && (*bol)) {
		char *endkey;
		RbtStatus status;

		eol = strchr(bol, '\n'); if (eol) *eol = '\0';

		/* Find the config entry */
		endkey = strchr(bol, '|'); if (endkey) endkey = strchr(endkey+1, '|'); 
		if (endkey) {
			critconf_t *cfg;
			char *ackstr, *ackrtimestr, *ackvtimestr, *acklevelstr, *ackbystr, *ackmsgstr;

			*endkey = '\0';
			cfg = get_critconfig(bol, CRITCONF_TIMEFILTER, NULL);
			*endkey = '|';

			if (cfg) {
				hstatus_t *newitem = (hstatus_t *)calloc(1, sizeof(hstatus_t));
				newitem->config     = cfg;
				newitem->hostname   = gettok(bol, "|");
				newitem->testname   = gettok(NULL, "|");
				newitem->color      = parse_color(gettok(NULL, "|"));
				newitem->lastchange = atoi(gettok(NULL, "|"));
				newitem->logtime    = atoi(gettok(NULL, "|"));
				newitem->validtime  = atoi(gettok(NULL, "|"));
				ackstr              = gettok(NULL, "|");
				ackrtimestr = ackvtimestr = acklevelstr = ackbystr = ackmsgstr = NULL;

				if (ackstr) {
					nldecode(ackstr);
					ackrtimestr = strtok(ackstr, ":");
					if (ackrtimestr) ackvtimestr = strtok(NULL, ":");
					if (ackvtimestr) acklevelstr = strtok(NULL, ":");
					if (acklevelstr) ackbystr = strtok(NULL, ":");
					if (ackbystr)    ackmsgstr = strtok(NULL, ":");
				}

				if ( (hostinfo(newitem->hostname) == NULL)  ||
				     (newitem->config->priority > maxprio)  ||
				     ((now - newitem->lastchange) > maxage) ||
				     (newitem->color < mincolor)            ||
				     (ackmsgstr && !wantacked)              ) {
					xfree(newitem);
				}
				else {
					if (ackvtimestr && ackbystr && ackmsgstr) {
						newitem->acktime = atoi(ackvtimestr);
						newitem->ackedby = strdup(ackbystr);
						newitem->ackmsg  = strdup(ackmsgstr);
					}

					newitem->key = (char *)malloc(strlen(newitem->hostname) + strlen(newitem->testname) + 2);
					sprintf(newitem->key, "%s|%s", newitem->hostname, newitem->testname);
					status = rbtInsert(rbstate, newitem->key, newitem);
				}
			}
		}

		bol = (eol ? (eol+1) : NULL);
	}

	return 0;
}
Exemple #13
0
state_t *load_state(dispsummary_t **sumhead)
{
	int hobbitdresult;
	char		fn[PATH_MAX];
	state_t		*newstate, *topstate;
	dispsummary_t	*newsum, *topsum;
	char 		*board = NULL;
	char		*nextline;
	int		done;
	logdata_t	log;
	sendreturn_t	*sres;

	dbgprintf("load_state()\n");

	sres = newsendreturnbuf(1, NULL);

	if (!reportstart && !snapshot) {
		char *dumpfn = getenv("BOARDDUMP");

		if (dumpfn) {
			/* Debugging - read data from a dump file */
			struct stat st;
			FILE *fd;

			hobbitdresult = BB_ETIMEOUT;
			if (stat(dumpfn, &st) == 0) {
				fd = fopen(dumpfn, "r");
				if (fd) {
					board = (char *)malloc(st.st_size + 1);
					fread(board, 1, st.st_size, fd);
					fclose(fd);
					hobbitdresult = BB_OK;
				}
			}
		}
		else {
			hobbitdresult = sendmessage("hobbitdboard fields=hostname,testname,color,flags,lastchange,logtime,validtime,acktime,disabletime,sender,cookie,line1,acklist", NULL, BBTALK_TIMEOUT, sres);
			board = getsendreturnstr(sres, 1);
		}
	}
	else {
		hobbitdresult = sendmessage("hobbitdboard fields=hostname,testname", NULL, BBTALK_TIMEOUT, sres);
		board = getsendreturnstr(sres, 1);
	}

	freesendreturnbuf(sres);

	if ((hobbitdresult != BB_OK) || (board == NULL) || (*board == '\0')) {
		errprintf("hobbitd status-board not available, code %d\n", hobbitdresult);
		return NULL;
	}

	if (reportstart || snapshot) {
		oldestentry = getcurrenttime(NULL);
		purplelog = NULL;
		purplelogfn = NULL;
	}
	else {
		if (purplelogfn) {
			purplelog = fopen(purplelogfn, "w");
			if (purplelog == NULL) errprintf("Cannot open purplelog file %s\n", purplelogfn);
			else fprintf(purplelog, "Stale (purple) logfiles as of %s\n\n", timestamp);
		}
	}

	topstate = NULL;
	topsum = NULL;

	done = 0; nextline = board;
	while (!done) {
		char *bol = nextline;
		char *onelog, *acklist;
		char *p;
		int i;

		nextline = strchr(nextline, '\n');
		if (nextline) { *nextline = '\0'; nextline++; } else done = 1;

		if (strlen(bol) == 0) {
			done = 1;
			continue;
		}

		memset(&log, 0, sizeof(log));
		onelog = strdup(bol);
		acklist = NULL;
		p = gettok(onelog, "|"); i = 0;
		while (p) {
			switch (i) {
			  /* hostname|testname|color|testflags|lastchange|logtime|validtime|acktime|disabletime|sender|cookie|1st line of message */
			  case  0: log.hostname = p; break;
			  case  1: log.testname = p; break;
			  case  2: log.color = parse_color(p); break;
			  case  3: log.testflags = p; break;
			  case  4: log.lastchange = atoi(p); break;
			  case  5: log.logtime = atoi(p); break;
			  case  6: log.validtime = atoi(p); break;
			  case  7: log.acktime = atoi(p); break;
			  case  8: log.disabletime = atoi(p); break;
			  case  9: log.sender = p; break;
			  case 10: log.cookie = atoi(p); break;
			  case 11: log.msg = p; break;
			  case 12: acklist = p; break;
			}

			p = gettok(NULL, "|");
			i++;
		}
		if (!log.msg) log.msg = "";
		sprintf(fn, "%s.%s", commafy(log.hostname), log.testname);

		/* Get the data */
		if (strncmp(fn, "summary.", 8) == 0) {
			if (!reportstart && !snapshot) {
				newsum = init_displaysummary(fn, &log);
				if (newsum) {
					newsum->next = topsum;
					topsum = newsum;
				}
			}
		}
		else {
			if (acklist && *acklist) {
				/*
				 * It's been acked. acklist looks like
				 * 1149489234:1149510834:1:henrik:Joe promised to take care of this right after lunch\n
				 * The "\n" is the delimiter between multiple acks.
				 */
				char *tok;

				tok = strtok(acklist, ":");
				if (tok) tok = strtok(NULL, ":");
				if (tok) log.acktime = atol(tok);
			}
			newstate = init_state(fn, &log);
			if (newstate) {
				newstate->next = topstate;
				topstate = newstate;
				if (reportstart && (newstate->entry->repinfo->reportstart < oldestentry)) {
					oldestentry = newstate->entry->repinfo->reportstart;
				}
			}
		}
		xfree(onelog);
	}

	generate_compactitems(&topstate);

	if (reportstart) sethostenv_report(oldestentry, reportend, reportwarnlevel, reportgreenlevel);
	if (purplelog) fclose(purplelog);

	*sumhead = topsum;
	return topstate;
}
Exemple #14
0
int main(int argc, char *argv[])
{
	int argi;
	char *envarea = NULL;
	int obeycookies = 1;
	char *accessfn = NULL;

	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], "--no-pin") == 0) {
			nopin = 1;
		}
		else if (strcmp(argv[argi], "--no-cookies") == 0) {
			obeycookies = 0;
		}
		else if (argnmatch(argv[argi], "--access=")) {
			char *p = strchr(argv[argi], '=');
			accessfn = strdup(p+1);
		}

	}

	redirect_cgilog("ack");

	cgidata = cgi_request();
	if ( (nopin && (cgi_method == CGI_GET)) || (!nopin && (cgidata == NULL)) ) {
		/* Present the query form */
		sethostenv("", "", "", colorname(COL_RED), NULL);

		printf("Content-Type: %s\n\n", xgetenv("HTMLCONTENTTYPE"));

		if (!nopin) {
			showform(stdout, "acknowledge", "acknowledge_form", COL_RED, getcurrenttime(NULL), 
				 NULL, NULL);
		}
		else {
			char *cmd;
			char *respbuf = NULL;
			char *hostname, *pagename;
			int gotfilter = 0, filtererror = 0;
			sendreturn_t *sres = NULL;
			int col, firstcolor = 1, alertcolors = colorset(xgetenv("ALERTCOLORS"), ((1 << COL_GREEN) | (1 << COL_BLUE)));

			headfoot(stdout, "acknowledge", "", "header", COL_RED);

			cmd = (char *)malloc(1024);
			strcpy(cmd, "xymondboard fields=hostname,testname,cookie color=");
			for (col = 0; (col < COL_COUNT); col++) {
				if ((1 << col) & alertcolors) {
					if (!firstcolor) strcat(cmd, ",");
					strcat(cmd, colorname(col));
					firstcolor = 0;
				}
			}
			// printf("<!-- cmd = %s -->\n", cmd);

			if (obeycookies && !gotfilter && ((hostname = get_cookie("host")) != NULL)) {
				if (*hostname) {
					pcre *dummy;
					char *re;
					
					re = (char *)malloc(3+strlen(hostname));
					sprintf(re, "^%s$", hostname);
					dummy = compileregex(re);
					if (dummy) {
						/* Valid expression */
						freeregex(dummy);
						cmd = (char *)realloc(cmd, 1024 + strlen(cmd) + strlen(re));
						sprintf(cmd + strlen(cmd), " host=%s", re);
						gotfilter = 1;
					}
					else {
						filtererror = 1;
						printf("<p align=\"center\">Invalid hostname filter</p>\n");
					}
				}
			}

			if (obeycookies && !gotfilter && ((pagename = get_cookie("pagepath")) != NULL)) {
				if (*pagename) {
					pcre *dummy;
					char *re;

					re = (char *)malloc(8 + strlen(pagename)*2);
					sprintf(re, "%s$|^%s/.+", pagename, pagename);
					dummy = compileregex(re);
					if (dummy) {
						/* Valid expression */
						freeregex(dummy);
						cmd = (char *)realloc(cmd, 1024 + strlen(cmd) + strlen(re));
						sprintf(cmd + strlen(cmd), " page=%s", re);
						gotfilter = 1;
					}
					else {
						filtererror = 1;
						printf("<p align=\"center\">Invalid pagename filter</p>\n");
					}
				}
			}

			sres = newsendreturnbuf(1, NULL);

			if (!filtererror && (sendmessage(cmd, NULL, XYMON_TIMEOUT, sres) == XYMONSEND_OK)) {
				char *bol, *eoln;
				int first = 1;

				respbuf = getsendreturnstr(sres, 1);

				bol = respbuf;
				while (bol) {
					char *hname, *tname, *ackcode;

					eoln = strchr(bol, '\n'); if (eoln) *eoln = '\0';
					hname = tname = ackcode = NULL;
					hname = strtok(bol, "|");
					if (hname) tname = strtok(NULL, "|");
					if (tname) ackcode = strtok(NULL, "|");
					if (hname && tname && ackcode && (strcmp(hname, "summary") != 0)) {
						if (first) {
							fprintf(stdout, "<form method=\"POST\" ACTION=\"%s\">\n", getenv("SCRIPT_NAME"));
							fprintf(stdout, "<center><table cellpadding=5 summary=\"Ack data\">\n");
							fprintf(stdout, "<tr><th align=left>Host</th><th align=left>Test</th><th align=left>Duration</th><th align=left>Cause</th><th>Ack</th><th>Ack Multiple</tr>\n");
							first = 0;
						}

						generate_ackline(stdout, hname, tname, ackcode);
					}

					if (eoln) bol = eoln+1; else bol = NULL;
				}

				if (first) {
					fprintf(stdout, "<center><font size=\"+1\"><b>No active alerts</b></font></center>\n");
				}
				else {
					generate_ackline(stdout, NULL, NULL, NULL);
					fprintf(stdout, "</table></center>\n");
					fprintf(stdout, "</form>\n");
				}
			}

			freesendreturnbuf(sres);

			headfoot(stdout, "acknowledge", "", "footer", COL_RED);
		}
	}
	else if ( (nopin && (cgi_method == CGI_POST)) || (!nopin && (cgidata != NULL)) ) {
		char *xymonmsg;
		char *acking_user = "";
		acklist_t *awalk;
		strbuffer_t *response = newstrbuffer(0);
		int count = 0;


		/* We only want to accept posts from certain pages */
		{ 
			char cgisource[1024]; char *p;
			p = csp_header("acknowledge"); if (p) fprintf(stdout, "%s", p);
			snprintf(cgisource, sizeof(cgisource), "%s/%s", xgetenv("SECURECGIBINURL"), "acknowledge");
			if (!cgi_refererok(cgisource)) {
				fprintf(stdout, "Location: %s.sh?\n\n", cgisource);
				return 0;
			}
		}

		parse_query();
		if (getenv("REMOTE_USER")) {
			char *remaddr = getenv("REMOTE_ADDR");

			acking_user = (char *)malloc(1024 + strlen(getenv("REMOTE_USER")) + (remaddr ? strlen(remaddr) : 0));
			sprintf(acking_user, "\nAcked by: %s", getenv("REMOTE_USER"));
			if (remaddr) sprintf(acking_user + strlen(acking_user), " (%s)", remaddr);
		}

		/* Load the host data (for access control) */
		if (accessfn) {
			load_hostnames(xgetenv("HOSTSCFG"), NULL, get_fqdn());
			load_web_access_config(accessfn);
		}

		addtobuffer(response, "<center>\n");
		for (awalk = ackhead; (awalk); awalk = awalk->next) {
			char *msgline = (char *)malloc(1024 + (awalk->hostname ? strlen(awalk->hostname) : 0) + (awalk->testname ? strlen(awalk->testname) : 0));

			if (!awalk->checked) continue;
			if (accessfn && (!web_access_allowed(getenv("REMOTE_USER"), awalk->hostname, awalk->testname, WEB_ACCESS_CONTROL))) continue;

			if ((reqtype == ACK_ONE) && (awalk->id != sendnum)) continue;

			if (reqtype == ACK_MANY) {
				if (!awalk->ackmsg) awalk->ackmsg = ackmsgall;
				if (!awalk->validity && validityall) awalk->validity = durationvalue(validityall);
				if (periodall) awalk->period = periodall;
			}

			if (strncmp(awalk->period, "hour", 4) == 0) awalk->validity *= 60; 
			else if (strncmp(awalk->period, "day", 4) == 0) awalk->validity *= 60*24;

			count++;
			if (!awalk->ackmsg || !awalk->validity || !awalk->acknum) {
				if (awalk->hostname && awalk->testname) {
					sprintf(msgline, "<b>NO ACK</b> sent for host %s / test %s",
						htmlquoted(awalk->hostname), htmlquoted(awalk->testname));
				}
				else {
					sprintf(msgline, "<b>NO ACK</b> sent for item %d", awalk->id);
				}
				addtobuffer(response, msgline);
				addtobuffer(response, ": Duration or message not set<br>\n");
				continue;
			}

			xymonmsg = (char *)malloc(1024 + strlen(awalk->ackmsg) + strlen(acking_user));
			sprintf(xymonmsg, "xymondack %d %d %s %s", awalk->acknum, awalk->validity, awalk->ackmsg, acking_user);
			if (sendmessage(xymonmsg, NULL, XYMON_TIMEOUT, NULL) == XYMONSEND_OK) {
				if (awalk->hostname && awalk->testname) {
					sprintf(msgline, "Acknowledge sent for host %s / test %s<br>\n", 
						htmlquoted(awalk->hostname), htmlquoted(awalk->testname));
				}
				else {
					sprintf(msgline, "Acknowledge sent for code %d<br>\n", awalk->acknum);
				}
			}
			else {
				if (awalk->hostname && awalk->testname) {
					sprintf(msgline, "Failed to send acknowledge for host %s / test %s<br>\n", 
						htmlquoted(awalk->hostname), htmlquoted(awalk->testname));
				}
				else {
					sprintf(msgline, "Failed to send acknowledge for code %d<br>\n", awalk->acknum);
				}
			}

			addtobuffer(response, msgline);
			xfree(xymonmsg);
		}

		if (count == 0) addtobuffer(response, "<b>No acks requested</b>\n");

		addtobuffer(response, "</center>\n");

		fprintf(stdout, "Content-type: %s\n\n", xgetenv("HTMLCONTENTTYPE"));
	
		headfoot(stdout, "acknowledge", "", "header", COL_RED);
		fprintf(stdout, "%s", STRBUF(response));
		headfoot(stdout, "acknowledge", "", "footer", COL_RED);
	}

	return 0;
}
Exemple #15
0
int main(int argc, char *argv[])
{
	int argi;
	char *versionfn, *inprogressfn;
	FILE *versionfd, *tarpipefd;
	char version[1024];
	char *newversion = NULL;
	char *newverreq;
	char *updateparam = NULL;
	int  removeself = 0;
	int talkstat = 0;
	sendreturn_t *sres;

#ifdef BIG_SECURITY_HOLE
	/* Immediately drop all root privs, we'll regain them later when needed */
	drop_root();
#else
	/* We WILL not run as suid-root. */
	drop_root_and_removesuid(argv[0]);
#endif

	versionfn = (char *)malloc(strlen(xgetenv("XYMONHOME")) + strlen(CLIENTVERSIONFILE) + 2);
	sprintf(versionfn, "%s/%s", xgetenv("XYMONHOME"), CLIENTVERSIONFILE);
	inprogressfn = (char *)malloc(strlen(xgetenv("XYMONHOME")) + strlen(INPROGRESSFILE) + 2);
	sprintf(inprogressfn, "%s/%s", xgetenv("XYMONHOME"), INPROGRESSFILE);

	versionfd = fopen(versionfn, "r");
	if (versionfd) {
		char *p;
		if (fgets(version, sizeof(version), versionfd) == NULL) *version = '\0';
		p = strchr(version, '\n'); if (p) *p = '\0';
		fclose(versionfd);
	}
	else {
		*version = '\0';
	}

	if (chdir(xgetenv("XYMONHOME")) != 0) {
		errprintf("Cannot chdir to XYMONHOME\n");
		return 1;
	}

	for (argi=1; (argi < argc); argi++) {
		if (strcmp(argv[argi], "--level") == 0) {
			/* For checking what version we're at */
			printf("%s\n", version);
			return 0;
		}
		else if (strcmp(argv[argi], "--reexec") == 0) {
			/*
			 * First step of the update procedure.
			 *
			 * To avoid problems with unpacking a new clientupdate
			 * on top of the running one (some tar's will abort
			 * if they try this), copy ourself to a temp. file and
			 * re-exec it to carry out the update.
			 */
			char tmpfn[PATH_MAX];
			char *srcfn;
			FILE *tmpfd, *srcfd;
			unsigned char buf[8192];
			long n;
			struct stat st;
			int cperr;

			if (!updateparam) {
				errprintf("clientupdate --reexec called with no update version\n");
				return 1;
			}

			if ( (stat(inprogressfn, &st) == 0) && ((getcurrenttime(NULL) - st.st_mtime) < 3600) ) {
				errprintf("Found update in progress or failed update (started %ld minutes ago)\n",
					(long) (getcurrenttime(NULL)-st.st_mtime)/60);
				return 1;
			}
			unlink(inprogressfn);
			tmpfd = fopen(inprogressfn, "w"); if (tmpfd) fclose(tmpfd);

			/* Copy the executable */
			srcfn = argv[0];
			srcfd = fopen(srcfn, "r"); cperr = errno;

			sprintf(tmpfn, "%s/.update.%s.%ld.tmp", 
				xgetenv("XYMONTMP"), xgetenv("MACHINEDOTS"), (long)getcurrenttime(NULL));

			dbgprintf("Starting update by copying %s to %s\n", srcfn, tmpfn);

			unlink(tmpfn);	/* To avoid symlink attacks */
			if (srcfd) { tmpfd = fopen(tmpfn, "w"); cperr = errno; }

			if (!srcfd || !tmpfd) {
				errprintf("Cannot copy executable: %s\n", strerror(cperr));
				return 1;
			}

			while ((n = fread(buf, 1, sizeof(buf), srcfd)) > 0) fwrite(buf, 1, n, tmpfd);
			fclose(srcfd); fclose(tmpfd);

			/* Make sure the temp. binary has execute permissions set */
			chmod(tmpfn, S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP);

			/*
			 * Set the temp. executable suid-root, and exec() it.
			 * If get_root() fails (because clientupdate was installed
			 * without suid-root privs), just carry on and do what we
			 * can without root privs. (It basically just means that
			 * logfetch() and clientupdate() will continue to run without
			 * root privs).
			 */
#ifdef BIG_SECURITY_HOLE
			get_root();
			chown(tmpfn, 0, getgid());
			chmod(tmpfn, S_ISUID|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP);
			drop_root();
#endif

			/* Run the temp. executable */
			dbgprintf("Running command '%s %s ..remove-self'\n", tmpfn, updateparam);
			execl(tmpfn, tmpfn, updateparam, "--remove-self", (char *)NULL);

			/* We should never go here */
			errprintf("exec() failed to launch update: %s\n", strerror(errno));
			return 1;
		}

		else if (strncmp(argv[argi], "--update=", 9) == 0) {
			newversion = strdup(argv[argi]+9);
			updateparam = argv[argi];
		}
		else if (strcmp(argv[argi], "--remove-self") == 0) {
			removeself = 1;
		}
		else if (strcmp(argv[argi], "--debug") == 0) {
			debug = 1;
		}

		else if (strcmp(argv[argi], "--suid-setup") == 0) {
			/*
			 * Final step of the update procedure.
			 *
			 * Become root to setup suid-root privs on utils that need it.
			 * Note: If get_root() fails, we're left with normal user privileges. That is
			 * OK, because that is how the client was installed originally, then.
			 */
#ifdef BIG_SECURITY_HOLE
			get_root();
			chown("bin/logfetch", 0, getgid());
			chmod("bin/logfetch", S_ISUID|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP);
			drop_root();
#endif

			return 0;
		}
	}

	if (!newversion) {
		errprintf("No new version string!\n");
		cleanup(inprogressfn, (removeself ? argv[0] : NULL));
		return 1;
	}

	/* Update to version "newversion" */
	dbgprintf("Opening pipe to 'tar'\n");
	tarpipefd = popen("tar xf -", "w");
	if (tarpipefd == NULL) {
		errprintf("Cannot launch 'tar xf -': %s\n", strerror(errno));
		cleanup(inprogressfn, (removeself ? argv[0] : NULL));
		return 1;
	}

	sres = newsendreturnbuf(1, tarpipefd);
	newverreq = (char *)malloc(100+strlen(newversion));
	sprintf(newverreq, "download %s.tar", newversion);
	dbgprintf("Sending command to Xymon: %s\n", newverreq);
	if ((talkstat = sendmessage(newverreq, NULL, XYMON_TIMEOUT, sres)) != XYMONSEND_OK) {
		errprintf("Cannot fetch new client tarfile: Status %d\n", talkstat);
		cleanup(inprogressfn, (removeself ? argv[0] : NULL));
		freesendreturnbuf(sres);
		return 1;
	}
	else {
		dbgprintf("Download command completed OK\n");
		freesendreturnbuf(sres);
	}

	dbgprintf("Closing tar pipe\n");
	if ((talkstat = pclose(tarpipefd)) != 0) {
		errprintf("Upgrade failed, tar exited with status %d\n", talkstat);
		cleanup(inprogressfn, (removeself ? argv[0] : NULL));
		return 1;
	}
	else {
		dbgprintf("tar pipe exited with status 0 (OK)\n");
	}

	/* Create the new version file */
	dbgprintf("Creating new version file %s with version %s\n", versionfn, newversion);
	unlink(versionfn);
	versionfd = fopen(versionfn, "w");
	if (versionfd) {
		fprintf(versionfd, "%s", newversion);
		fclose(versionfd);
	}
	else {
		errprintf("Cannot create version file: %s\n", strerror(errno));
	}

	/* Make sure these have execute permissions */
	dbgprintf("Setting execute permissions on xymonclient.sh and clientupdate tools\n");
	chmod("bin/xymonclient.sh", S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP);
	chmod("bin/clientupdate", S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP);

	/*
	 * Become root to setup suid-root privs on the new clientupdate util.
	 * Note: If get_root() fails, we're left with normal user privileges. That is
	 * OK, because that is how the client was installed originally, then.
	 */
#ifdef BIG_SECURITY_HOLE
	get_root();
	chown("bin/clientupdate", 0, getgid());
	chmod("bin/clientupdate", S_ISUID|S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP);
	drop_root();
#endif

	dbgprintf("Cleaning up after update\n");
	cleanup(inprogressfn, (removeself ? argv[0] : NULL));

	/*
	 * Exec the new client-update utility to fix suid-root permissions on
	 * the new files.
	 */
	execl("bin/clientupdate", "bin/clientupdate", "--suid-setup", (char *)NULL);

	/* We should never go here */
	errprintf("exec() of clientupdate --suid-setup failed: %s\n", strerror(errno));

	return 0;
}