Exemplo n.º 1
0
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);
	}
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
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);
	}
}
Exemplo n.º 4
0
static void meta_add(strbuffer_t *buf)
{
	/* Check if there is room for the message + 2 newlines */
	if (maxmsgspercombo && (xymonmetaqueued >= maxmsgspercombo)) {
		/* Nope ... flush buffer */
		meta_flush();
	}
	else {
		/* Yep ... add delimiter before new status (but not before the first!) */
		if (xymonmetaqueued) addtobuffer(metamsg, "\n\n");
	}

	addtostrbuffer(metamsg, buf);
	xymonmetaqueued++;
}
Exemplo n.º 5
0
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);
	}
}
Exemplo n.º 6
0
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);
}
Exemplo n.º 7
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;
			}
		}
	}
}
Exemplo n.º 8
0
void addtostrstatus(strbuffer_t *p)
{
	addtostrbuffer(msgbuf, p);
}
Exemplo n.º 9
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);
}