Exemple #1
0
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);
}
Exemple #2
0
void init_status(int color)
{
	if (msgbuf == NULL) msgbuf = newstrbuffer(0);
	clearstrbuffer(msgbuf);
	msgcolor = color;
	xymonstatuscount++;
}
Exemple #3
0
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, "&quot;"); break;
		  case '&': addtobuffer(result, "&amp;"); break;
		  case '<': addtobuffer(result, "&lt;"); break;
		  case '>': addtobuffer(result, "&gt;"); break;
		  case ' ': addtobuffer(result, "&nbsp;"); break;
		  default: break;
		}
		inp = (c == '\0') ? NULL : endp+1;
	} while (inp);

	return STRBUF(result);
}
Exemple #4
0
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;
}
Exemple #5
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);
	}
}
Exemple #7
0
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);
	}
}
Exemple #10
0
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);
}
Exemple #11
0
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);
}
Exemple #12
0
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;
}
Exemple #13
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);
}
Exemple #14
0
void meta_start(void)
{
	if (metamsg == NULL) metamsg = newstrbuffer(0);
	clearstrbuffer(metamsg);
	xymonmetaqueued = 0;
}
Exemple #15
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;
}
Exemple #16
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;
}
Exemple #17
0
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;
}
Exemple #18
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;
}
Exemple #19
0
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);
}
Exemple #20
0
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);
}
Exemple #21
0
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);
}
Exemple #22
0
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;
			}
		}
	}
}
Exemple #23
0
void init_meta(char *metaname)
{
	if (metabuf == NULL) metabuf = newstrbuffer(0);
	clearstrbuffer(metabuf);
}
Exemple #24
0
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);
}
Exemple #26
0
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;
}