Пример #1
0
static void combo_flush(void)
{

	if (!xymonmsgqueued) {
		dbgprintf("Flush, but xymonmsg is empty\n");
		return;
	}

	if (debug) {
		char *p1, *p2;

		dbgprintf("Flushing combo message\n");
		p1 = p2 = STRBUF(xymonmsg);

		do {
			p2++;
			p1 = strstr(p2, "\nstatus ");
			if (p1) {
				p1++; /* Skip the newline */
				p2 = strchr(p1, '\n');
				if (p2) *p2='\0';
				printf("      %s\n", p1);
				if (p2) *p2='\n';
			}
		} while (p1 && p2);
	}

	sendmessage(STRBUF(xymonmsg), NULL, XYMON_TIMEOUT, NULL);
	combo_start();	/* Get ready for the next */
}
Пример #2
0
void finish_status(void)
{
	if (debug) {
		char *p = strchr(STRBUF(msgbuf), '\n');

		if (p) *p = '\0';
		dbgprintf("Adding to combo msg: %s\n", STRBUF(msgbuf));
		if (p) *p = '\n';
	}

	combo_add(msgbuf);
}
Пример #3
0
void loadenv(char *envfile, char *area)
{
	FILE *fd;
	strbuffer_t *inbuf;
	char *p, *oneenv;
	int n;

	MEMDEFINE(l);
	inbuf = newstrbuffer(0);

	fd = stackfopen(envfile, "r", NULL);
	if (fd) {
		while (stackfgets(inbuf, NULL)) {
			sanitize_input(inbuf, 1, 1);

			if (STRBUFLEN(inbuf) && strchr(STRBUF(inbuf), '=')) {
				/*
				 * Do the environment "area" stuff: If the input
				 * is of the form AREA/NAME=VALUE, then setup the variable
				 * only if we're called with the correct AREA setting.
				 */
				oneenv = NULL;

				p = STRBUF(inbuf) + strcspn(STRBUF(inbuf), "=/");
				if (*p == '/') {
					if (area) {
						*p = '\0';
						if (strcasecmp(STRBUF(inbuf), area) == 0) oneenv = strdup(expand_env(p+1));
					}
				}
				else oneenv = strdup(expand_env(STRBUF(inbuf)));

				if (oneenv) {
					p = strchr(oneenv, '=');
					if (*(p+1) == '"') {
						/* Move string over the first '"' */
						memmove(p+1, p+2, strlen(p+2)+1);
						/* Kill a trailing '"' */
						if (*(oneenv + strlen(oneenv) - 1) == '"') *(oneenv + strlen(oneenv) - 1) = '\0';
					}
					n = putenv(oneenv);
				}
			}
		}
		stackfclose(fd);
	}
	else {
		errprintf("Cannot open env file %s - %s\n", envfile, strerror(errno));
	}

	freestrbuffer(inbuf);
	MEMUNDEFINE(l);
}
Пример #4
0
void load_state(char *filename, char *statusbuf)
{
    FILE *fd = fopen(filename, "r");
    strbuffer_t *inbuf;
    char *p;

    if (fd == NULL) return;

    initfgets(fd);
    inbuf = newstrbuffer(0);
    while (unlimfgets(inbuf, fd)) {
        sanitize_input(inbuf, 0, 0);

        p = strchr(STRBUF(inbuf), '|');
        if (p) {
            repeat_t *newrpt;

            *p = '\0';
            if (atoi(STRBUF(inbuf)) > getcurrenttime(NULL)) {
                char *found = NULL;

                if (statusbuf) {
                    char *htend;

                    /* statusbuf contains lines with "HOSTNAME|TESTNAME|COLOR" */
                    htend = strchr(p+1, '|');
                    if (htend) htend = strchr(htend+1, '|');
                    if (htend) {
                        *htend = '\0';
                        *p = '\n';
                        found = strstr(statusbuf, p);
                        if (!found && (strncmp(statusbuf, p+1, strlen(p+1)) == 0))
                            found = statusbuf;
                        *htend = '|';
                    }
                }
                if (!found) continue;

                newrpt = (repeat_t *)malloc(sizeof(repeat_t));
                newrpt->recipid = strdup(p+1);
                newrpt->nextalert = atoi(STRBUF(inbuf));
                newrpt->next = rpthead;
                rpthead = newrpt;
            }
        }
    }

    fclose(fd);
    freestrbuffer(inbuf);
}
Пример #5
0
void *load_web_access_config(char *accessfn)
{
	FILE *fd;
	strbuffer_t *buf;

	if (acctree) return 0;
	acctree = xtreeNew(strcasecmp);

	fd = stackfopen(accessfn, "r", NULL);
	if (fd == NULL) return NULL;

	buf = newstrbuffer(0);
	while (stackfgets(buf, NULL)) {
		char *group, *member;
		char *key;

		group = strtok(STRBUF(buf), ": \n");
		if (!group) continue;

		member = strtok(NULL, ", \n");
		while (member) {
			key = (char *)malloc(strlen(group) + strlen(member) + 2);
			sprintf(key, "%s %s", group, member);
			xtreeAdd(acctree, key, NULL);
			member = strtok(NULL, ", \n");
		}
	}
	stackfclose(fd);

	return acctree;
}
Пример #6
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);
}
Пример #7
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);
}
Пример #8
0
Файл: zvm.c Проект: tjyang/abmon
static void zvm_mdc_report(char *hostname, char *clientclass, enum ostype_t os,
                     void *hinfo, char *fromline, char *timestr, char *cpuutilstr)
{
        char *p;
        int mdcreads, mdcwrites, mdchitpct;
        char mdcresult[100];

        char msgline[256];
        strbuffer_t *msg;

        if (!cpuutilstr) return;
        msg = newstrbuffer(0);

        /*
         *  Looking for MDC info in 'IND' command response
         *  MDC READS-000001/SEC WRITES-000001/SEC HIT RATIO-098%
         */
        *mdcresult = '\0';
        /*  Skip past three newlines in message to the PAGING text  */
        p=strstr(cpuutilstr,"READS-");
        if (p) {
		p += 6;
        	sscanf(p, "%d/SEC", &mdcreads);
        	p=strstr(cpuutilstr,"WRITES-") + 7;
        	sscanf(p, "%d/SEC", &mdcwrites);
        	p=strstr(cpuutilstr,"RATIO-") + 6;
        	sscanf(p, "%d", &mdchitpct);

	        sprintf(msgline, "data %s.mdc\n%s\n%d:%d:%d\n", commafy(hostname), osname(os), mdcreads, mdcwrites, mdchitpct);
        	addtobuffer(msg, msgline);
		sendmessage(STRBUF(msg), NULL, BBTALK_TIMEOUT, NULL);
        	}

        freestrbuffer(msg);
}
Пример #9
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;
		}
	}
}
Пример #10
0
static void meta_flush(void)
{
	if (!xymonmetaqueued) {
		dbgprintf("Flush, but xymonmeta is empty\n");
		return;
	}

	sendmessage(STRBUF(metamsg), NULL, XYMON_TIMEOUT, NULL);
	meta_start();	/* Get ready for the next */
}
Пример #11
0
int main(int argc, char *argv[])
{
	char *fn, *p;
	char cmd[1024];
	FILE *fd;
	strbuffer_t *inbuf = newstrbuffer(0);
	void *listhead = NULL;
	int done, linenum;

	fn = strdup(argv[1]);
	strcpy(cmd, "!");
	done = 0;
	while (!done) {
		if (*cmd == '!') {
			fd = stackfopen(fn, "r", &listhead);
			linenum = 1;
			if (!fd) { errprintf("Cannot open file %s\n", fn); continue; }

			while (stackfgets(inbuf, NULL)) {
				linenum++;
				printf("%s", STRBUF(inbuf));
			}
			stackfclose(fd);
		}
		else if (*cmd == '?') {
			filelist_t *walk = (filelist_t *)listhead;

			while (walk) {
				printf("%s %lu\n", walk->filename, (unsigned long)walk->fsize);
				walk = walk->next;
			}
			if (stackfmodified(listhead)) printf("File(s) have been modified\n");
			else printf("No changes\n");
		}
		else if (*cmd == '.') {
			done = 1;
			continue;
		}
		else {
			xfree(fn); fn = strdup(cmd);
			stackfclist(&listhead);
			strcpy(cmd, "!");
			continue;
		}

		printf("\nCmd: "); fflush(stdout);
		fgets(cmd, sizeof(cmd), stdin);
		p = strchr(cmd, '\n'); if (p) *p = '\0';
	}

	xfree(fn);
	stackfclist(&listhead);

	return 0;
}
Пример #12
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);
	}
}
Пример #13
0
int main(int argc, char *argv[])
{ 
	FILE *bbhosts;
	char *fn = NULL;
	strbuffer_t *inbuf;
	int argi;
	char *include2 = NULL;


	for (argi=1; (argi < argc); argi++) {
		if (strcmp(argv[argi], "--version") == 0) {
			printf("bbhostshow version %s\n", VERSION);
			exit(0);
		}
		else if (strcmp(argv[argi], "--help") == 0) {
			printf("Usage:\n%s [filename]\n", argv[0]);
			exit(0);
		}
		else if (strcmp(argv[argi], "--bbnet") == 0) {
			include2 = "netinclude";
		}
		else if (strcmp(argv[argi], "--bbdisp") == 0) {
			include2 = "dispinclude";
		}
		else if (*argv[argi] != '-') {
			fn = strdup(argv[argi]);
		}
	}

	if (!fn || (strlen(fn) == 0)) {
		fn = getenv("BBHOSTS");
		if (!fn) {
			errprintf("Environment variable BBHOSTS is not set - aborting\n");
			exit(2);
		}
	}

	bbhosts = stackfopen(fn, "r", NULL);
	if (bbhosts == NULL) {
		printf("Cannot open the BBHOSTS file '%s'\n", fn);
		exit(1);
	}

	inbuf = newstrbuffer(0);
	while (stackfgets(inbuf, include2)) {
		printf("%s", STRBUF(inbuf));
	}

	stackfclose(bbhosts);
	freestrbuffer(inbuf);
	return 0;
}
Пример #14
0
void test_is_done(myconn_t *rec)
{
	rec->testendtime = getcurrenttime(NULL);
	list_item_move(donetests, rec->listitem, rec->testspec);
	free_net_dialog(rec->dialog, rec->dialogtoken);

	if (!rec->ignoreresult && !rec->noredirect && (rec->talkprotocol == TALK_PROTO_HTTP) && (rec->httpstatus >= 300) && (rec->httpstatus <= 399) && (rec->redircount < MAXREDIRECTS)) {
		/* HTTP redirect */
		char *lochdr;
		lochdr = strstr(STRBUF(rec->httpheaders), "\nLocation:");

		rec->ignoreresult = 1;

		if (lochdr) {
			char *locend, savchar;
			char **dialog;
			int dtoken, advtest = 0;
			net_test_options_t options;
			myconn_netparams_t netparams;
			myconn_t *newtest;

			lochdr += strlen("\nLocation:"); lochdr += strspn(lochdr, " \t");
			locend = lochdr + strcspn(lochdr, "\r\n");
			savchar = *locend; *locend = '\0';

			/* Copy options from the original test */
			memset(&options, 0, sizeof(options));
			options.testtype = NET_TEST_HTTP;
			options.timeout = rec->timeout;
			options.interval = rec->interval;
			options.testid = rec->testid;
			options.sourceip = (rec->netparams.sourceip ? strdup(rec->netparams.sourceip) : NULL);

			memset(&netparams, 0, sizeof(netparams));
			dialog = net_dialog(rec->testspec, &netparams, &options, rec->hostinfo, &dtoken, lochdr);
			newtest = add_net_test(rec->testspec, dialog, dtoken, &options, &netparams, rec->hostinfo);
			*locend = savchar;

			/* 
			 * Flag the original result record so it is not transmitted as part of the result data.
			 * Bump redirect counter so we wont end up looping.
			 */
			newtest->teststarttime = rec->teststarttime;
			newtest->redircount = rec->redircount + 1;
		}
	}
}
Пример #15
0
void do_extensions(FILE *output, char *extenv, char *family)
{
	/*
	 * Extension scripts. These are ad-hoc, and implemented as a
	 * simple pipe. So we do a fork here ...
	 */

	char *exts, *p;
	FILE *inpipe;
	char extfn[PATH_MAX];
	strbuffer_t *inbuf;

	p = xgetenv(extenv);
	if (p == NULL) {
		/* No extension */
		return;
	}

	MEMDEFINE(extfn);

	exts = strdup(p);
	p = strtok(exts, "\t ");
	inbuf = newstrbuffer(0);

	while (p) {
		/* Dont redo the eventlog or acklog things */
		if ((strcmp(p, "eventlog.sh") != 0) &&
		    (strcmp(p, "acklog.sh") != 0)) {
			sprintf(extfn, "%s/ext/%s/%s", xgetenv("XYMONHOME"), family, p);
			inpipe = popen(extfn, "r");
			if (inpipe) {
				initfgets(inpipe);
				while (unlimfgets(inbuf, inpipe)) fputs(STRBUF(inbuf), output);
				pclose(inpipe);
				freestrbuffer(inbuf);
			}
		}
		p = strtok(NULL, "\t ");
	}

	xfree(exts);

	MEMUNDEFINE(extfn);
	MEMUNDEFINE(buf);
}
Пример #16
0
void senddata(conn_t *conn)
{
	int n, togo;
	char *startp;

	/* Send data on the connection socket */
	togo = STRBUFLEN(conn->msgbuf) - conn->sentbytes;
	startp = STRBUF(conn->msgbuf) + conn->sentbytes;
	n = write(conn->sockfd, startp, togo);

	if (n <= -1) {
		/* Write failure */
		errprintf("Connection lost during write to %s\n", inet_ntoa(conn->caddr.sin_addr));
		conn->action = C_DONE;
	}
	else {
		conn->sentbytes += n;
		if (conn->sentbytes == STRBUFLEN(conn->msgbuf)) conn->action = C_DONE;
	}
}
Пример #17
0
char *getsendreturnstr(sendreturn_t *s, int takeover)
{
	char *result = NULL;

	if (!s) return NULL;
	if (!s->respstr) return NULL;
	result = STRBUF(s->respstr);
	if (takeover) {
		/*
		 * We cannot leave respstr as NULL, because later calls 
		 * to sendmessage() might re-use this sendreturn_t struct
		 * and expect to get the data back. So allocate a new
		 * responsebuffer for future use - if it isn't used, it
		 * will be freed by freesendreturnbuf().
		 */
		s->respstr = newstrbuffer(0);
	}

	return result;
}
Пример #18
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);
}
Пример #19
0
void load_columndocs(void)
{
    char fn[PATH_MAX];
    FILE *fd;
    strbuffer_t *inbuf;

    sprintf(fn, "%s/etc/columndoc.csv", xgetenv("BBHOME"));
    fd = fopen(fn, "r");
    if (!fd) return;

    inbuf = newstrbuffer(0);
    initfgets(fd);

    /* Skip the header line */
    if (!unlimfgets(inbuf, fd)) {
        fclose(fd);
        freestrbuffer(inbuf);
        return;
    }

    while (unlimfgets(inbuf, fd)) {
        char *s1 = NULL, *s2 = NULL;

        s1 = strtok(STRBUF(inbuf), coldelim);
        if (s1) s2 = strtok(NULL, coldelim);

        if (s1 && s2) {
            coltext_t *newitem = (coltext_t *)calloc(1, sizeof(coltext_t));
            newitem->colname = strdup(s1);
            newitem->coldescr = strdup(s2);
            newitem->next = chead;
            chead = newitem;
            ccount++;
        }
    }
    fclose(fd);
    freestrbuffer(inbuf);
}
Пример #20
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);
}
Пример #21
0
void readconfig(char *cfgfn, int verbose)
{
	static void *cfgfiles = NULL;
	FILE *cfgfd;
	strbuffer_t *inbuf;

	struct req_t *reqitem = NULL;
	int tasksleep = atoi(xgetenv("TASKSLEEP"));

	mibdef_t *mib;

	/* Check if config was modified */
	if (cfgfiles) {
		if (!stackfmodified(cfgfiles)) {
			dbgprintf("No files changed, skipping reload\n");
			return;
		}
		else {
			stackfclist(&cfgfiles);
			cfgfiles = NULL;
		}
	}

	cfgfd = stackfopen(cfgfn, "r", &cfgfiles);
	if (cfgfd == NULL) {
		errprintf("Cannot open configuration files %s\n", cfgfn);
		return;
	}

	inbuf = newstrbuffer(0);
	while (stackfgets(inbuf, NULL)) {
		char *bot, *p, *mibidx;
		char savech;

		sanitize_input(inbuf, 0, 0);
		bot = STRBUF(inbuf) + strspn(STRBUF(inbuf), " \t");
		if ((*bot == '\0') || (*bot == '#')) continue;

		if (*bot == '[') {
			char *intvl = strchr(bot, '/');

			/*
			 * See if we're running a non-standard interval.
			 * If yes, then process only the records that match
			 * this TASKSLEEP setting.
			 */
			if (tasksleep != 300) {
				/* Non-default interval. Skip the host if it HASN'T got an interval setting */
				if (!intvl) continue;

				/* Also skip the hosts that have an interval different from the current */
				*intvl = '\0';	/* Clip the interval from the hostname */
				if (atoi(intvl+1) != tasksleep) continue;
			}
			else {
				/* Default interval. Skip the host if it HAS an interval setting */
				if (intvl) continue;
			}

			reqitem = (req_t *)calloc(1, sizeof(req_t));

			p = strchr(bot, ']'); if (p) *p = '\0';
			reqitem->hostname = strdup(bot + 1);
			if (p) *p = ']';

			reqitem->hostip[0] = reqitem->hostname;
			reqitem->version = SNMP_VERSION_1;
			reqitem->authmethod = SNMP_V3AUTH_MD5;
			reqitem->next = reqhead;
			reqhead = reqitem;

			continue;
		}

		/* If we have nowhere to put the data, then skip further processing */
		if (!reqitem) continue;

		if (strncmp(bot, "ip=", 3) == 0) {
			char *nextip = strtok(strdup(bot+3), ",");
			int i = 0;

			do {
				reqitem->hostip[i++] = nextip;
				nextip = strtok(NULL, ",");
			} while (nextip);
			continue;
		}

		if (strncmp(bot, "version=", 8) == 0) {
			switch (*(bot+8)) {
			  case '1': reqitem->version = SNMP_VERSION_1; break;
			  case '2': reqitem->version = SNMP_VERSION_2c; break;
			  case '3': reqitem->version = SNMP_VERSION_3; break;
			}
			continue;
		}

		if (strncmp(bot, "community=", 10) == 0) {
			reqitem->community = strdup(bot+10);
			continue;
		}

		if (strncmp(bot, "username="******"passphrase=", 10) == 0) {
			reqitem->passphrase = strdup(bot+10);
			continue;
		}

		if (strncmp(bot, "authmethod=", 10) == 0) {
			if (strcasecmp(bot+10, "md5") == 0)
				reqitem->authmethod = SNMP_V3AUTH_MD5;
			else if (strcasecmp(bot+10, "sha1") == 0)
				reqitem->authmethod = SNMP_V3AUTH_SHA1;
			else
				errprintf("Unknown SNMPv3 authentication method '%s'\n", bot+10);

			continue;
		}

		/* Custom mibs */
		p = bot + strcspn(bot, "= \t\r\n"); savech = *p; *p = '\0';
		mib = find_mib(bot);
		*p = savech; 
		p += strspn(p, "= \t");
		mibidx = p;
		if (mib) {
			int i;
			mibidx_t *iwalk = NULL;
			char *oid, *oidbuf;
			char *devname;
			oidset_t *swalk;

			setupmib(mib, verbose);
			if (mib->loadstatus != MIB_STATUS_LOADED) continue;	/* Cannot use this MIB */

			/* See if this is an entry where we must determine the index ourselves */
			if (*mibidx) {
				for (iwalk = mib->idxlist; (iwalk && (*mibidx != iwalk->marker)); iwalk = iwalk->next) ;
			}

			if ((*mibidx == '*') && !iwalk) {
				errprintf("Cannot do wildcard matching without an index (host %s, mib %s)\n",
					  reqitem->hostname, mib->mibname);
				continue;
			}

			if (!iwalk) {
				/* No key lookup */
				swalk = mib->oidlisthead;
				while (swalk) {
					reqitem->setnumber++;

					for (i=0; (i <= swalk->oidcount); i++) {
						if (*mibidx) {
							oid = oidbuf = (char *)malloc(strlen(swalk->oids[i].oid) + strlen(mibidx) + 2);
							sprintf(oidbuf, "%s.%s", swalk->oids[i].oid, mibidx);
							devname = mibidx;
						}
						else {
							oid = swalk->oids[i].oid;
							oidbuf = NULL;
							devname = "-";
						}

						make_oitem(mib, devname, &swalk->oids[i], oid, reqitem);
						if (oidbuf) xfree(oidbuf);
					}

					swalk = swalk->next;
				}

				reqitem->next_oid = reqitem->oidhead;
			}
			else {
				/* Add a key-record so we can try to locate the index */
				keyrecord_t *newitem = (keyrecord_t *)calloc(1, sizeof(keyrecord_t));
				char endmarks[6];

				mibidx++;	/* Skip the key-marker */
				sprintf(endmarks, "%s%c", ")]}>", iwalk->marker);
				p = mibidx + strcspn(mibidx, endmarks); *p = '\0';
				newitem->key = strdup(mibidx);
				newitem->indexmethod = iwalk;
				newitem->mib = mib;
				newitem->next = reqitem->keyrecords;
				reqitem->currentkey = reqitem->keyrecords = newitem;
			}

			continue;
		}
		else {
			errprintf("Unknown MIB (not in snmpmibs.cfg): '%s'\n", bot);
		}
	}

	stackfclose(cfgfd);
	freestrbuffer(inbuf);
}
Пример #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;
			}
		}
	}
}
Пример #23
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;
}
Пример #24
0
void loadenv(char *envfile, char *area)
{
	FILE *fd;
	strbuffer_t *inbuf;
	char *p, *oneenv;

	MEMDEFINE(l);
	inbuf = newstrbuffer(0);

	fd = stackfopen(envfile, "r", NULL);
	if (fd) {
		while (stackfgets(inbuf, NULL)) {
			char *equalpos;
			int appendto = 0;

			sanitize_input(inbuf, 1, 1);

			if ((STRBUFLEN(inbuf) == 0) || ((equalpos = strchr(STRBUF(inbuf), '=')) == NULL)) continue;

			appendto = ((equalpos > STRBUF(inbuf)) && (*(equalpos-1) == '+'));

			/*
			 * Do the environment "area" stuff: If the input
			 * is of the form AREA/NAME=VALUE, then setup the variable
			 * only if we're called with the correct AREA setting.
			 */
			oneenv = NULL;

			p = STRBUF(inbuf) + strcspn(STRBUF(inbuf), "=/");
			if (*p == '/') {
				if (area) {
					*p = '\0';
					if (strcasecmp(STRBUF(inbuf), area) == 0) oneenv = strdup(expand_env(p+1));
				}
			}
			else oneenv = strdup(expand_env(STRBUF(inbuf)));

			if (oneenv) {
				p = strchr(oneenv, '=');
				if (*(p+1) == '"') {
					/* Move string over the first '"' */
					memmove(p+1, p+2, strlen(p+2)+1);
					/* Kill a trailing '"' */
					if (*(oneenv + strlen(oneenv) - 1) == '"') *(oneenv + strlen(oneenv) - 1) = '\0';
				}

				if (appendto) {
					char *oldval, *addstring, *p;

					addstring = strchr(oneenv, '='); if (addstring) { *addstring = '\0'; addstring++; }
					p = strchr(oneenv, '+'); if (p) *p = '\0';

					oldval = getenv(oneenv);
					if (oldval) {
						char *combinedenv = (char *)malloc(strlen(oneenv) + strlen(oldval) + strlen(addstring) + 2);
						sprintf(combinedenv, "%s=%s%s", oneenv, oldval, (addstring));
						xfree(oneenv);
						oneenv = combinedenv;
					}
					else {
						/* oneenv is now VARxxVALUE, so fix it to be a normal env. variable format */
						strcat(oneenv, "=");
						memmove(oneenv+strlen(oneenv), addstring, strlen(addstring) + 1);
					}
				}

				if (putenv(oneenv) != 0) errprintf("Cannot set environment: %s\n", strerror(errno));
			}
		}
		stackfclose(fd);
	}
	else {
		errprintf("Cannot open env file %s - %s\n", envfile, strerror(errno));
	}

	freestrbuffer(inbuf);
	MEMUNDEFINE(l);
}
Пример #25
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);
}
Пример #26
0
char *hostscfg_content(void)
{
	return strdup(STRBUF(contentbuffer));
}
Пример #27
0
char *stackfgets(strbuffer_t *buffer, char *extraincl)
{
	char *result;

	result = unlimfgets(buffer, fdhead->fd);

	if (result) {
		char *bufpastwhitespace = STRBUF(buffer) + strspn(STRBUF(buffer), " \t");

		if ( (strncmp(bufpastwhitespace, "include ", 8) == 0) ||
		     (extraincl && (strncmp(bufpastwhitespace, extraincl, strlen(extraincl)) == 0)) ) {
			char *newfn, *eol, eolchar;

			eol = bufpastwhitespace + strcspn(bufpastwhitespace, "\r\n"); if (eol) { eolchar = *eol; *eol = '\0'; }
			newfn = bufpastwhitespace + strcspn(bufpastwhitespace, " \t");
			newfn += strspn(newfn, " \t");
		
			if (*newfn && (stackfopen(newfn, "r", (void **)fdhead->listhead) != NULL))
				return stackfgets(buffer, extraincl);
			else {
				errprintf("WARNING: Cannot open include file '%s', line was:%s\n", 
					  newfn, STRBUF(buffer));
				if (eol) *eol = eolchar;
				return result;
			}
		}
		else if (strncmp(bufpastwhitespace, "directory ", 10) == 0) {
			char *dirfn, *eol, eolchar;

			eol = bufpastwhitespace + strcspn(bufpastwhitespace, "\r\n"); if (eol) { eolchar = *eol; *eol = '\0'; }
			dirfn = bufpastwhitespace + 9;
			dirfn += strspn(dirfn, " \t");

			if (*dirfn) addtofnlist(dirfn, (void **)fdhead->listhead);
			if (fnlist && (stackfopen(fnlist->name, "r", (void **)fdhead->listhead) != NULL)) {
				htnames_t *tmp = fnlist;

				fnlist = fnlist->next;
				xfree(tmp->name); xfree(tmp);
				return stackfgets(buffer, extraincl);
			}
			else if (fnlist) {
				htnames_t *tmp = fnlist;

				errprintf("WARNING: Cannot open include file '%s', line was:%s\n", fnlist->name, buffer);
				fnlist = fnlist->next;
				xfree(tmp->name); xfree(tmp);
				if (eol) *eol = eolchar;
				return result;
			}
			else {
				/* Empty directory include - return a blank line */
				*result = '\0'; 
				return result;
			}
		}
	}
	else if (result == NULL) {
		/* end-of-file on read */
		stackfclose(NULL);
		if (fnlist) {
			if (stackfopen(fnlist->name, "r", (void **)fdhead->listhead) != NULL) {
				htnames_t *tmp = fnlist;

				fnlist = fnlist->next;
				xfree(tmp->name); xfree(tmp);
				return stackfgets(buffer, extraincl);
			}
			else {
				htnames_t *tmp = fnlist;

				errprintf("WARNING: Cannot open include file '%s', line was:%s\n", fnlist->name, buffer);
				fnlist = fnlist->next;
				xfree(tmp->name); xfree(tmp);
				return result;
			}
		}
		else if (fdhead != NULL)
			return stackfgets(buffer, extraincl);
		else
			return NULL;
	}

	return result;
}
Пример #28
0
static void print_host(hostlist_t *host, htnames_t *testnames[], int testcount)
{
    int testi, rowcount, netcount;
    void *hinfo = hostinfo(host->hostname);
    char *dispname = NULL, *clientalias = NULL, *comment = NULL, *description = NULL, *pagepathtitle = NULL;
    char *net = NULL, *nkalerts = NULL;
    char *nktime = NULL, *downtime = NULL, *reporttime = NULL;
    char *itm;
    tag_t *taghead = NULL;
    int contidx = 0, haveping = 0;
    char contcol[1024];
    activealerts_t *alert;
    strbuffer_t *buf = newstrbuffer(0);

    fprintf(stdout, "<p style=\"page-break-before: always\">\n");
    fprintf(stdout, "<table width=\"100%%\" border=1 summary=\"%s configuration\">\n", host->hostname);

    pagepathtitle = bbh_item(hinfo, BBH_PAGEPATHTITLE);
    if (!pagepathtitle || (strlen(pagepathtitle) == 0)) pagepathtitle = "Top page";
    dispname = bbh_item(hinfo, BBH_DISPLAYNAME);
    if (dispname && (strcmp(dispname, host->hostname) == 0)) dispname = NULL;
    clientalias = bbh_item(hinfo, BBH_CLIENTALIAS);
    if (clientalias && (strcmp(clientalias, host->hostname) == 0)) clientalias = NULL;
    comment = bbh_item(hinfo, BBH_COMMENT);
    description = bbh_item(hinfo, BBH_DESCRIPTION);
    net = bbh_item(hinfo, BBH_NET);
    nkalerts = bbh_item(hinfo, BBH_NK);
    nktime = bbh_item(hinfo, BBH_NKTIME);
    if (!nktime) nktime = "24x7";
    else nktime = strdup(timespec_text(nktime));
    downtime = bbh_item(hinfo, BBH_DOWNTIME);
    if (downtime) downtime = strdup(timespec_text(downtime));
    reporttime = bbh_item(hinfo, BBH_REPORTTIME);
    if (!reporttime) reporttime = "24x7";
    else reporttime = strdup(timespec_text(reporttime));

    rowcount = 1;
    if (pagepathtitle) rowcount++;
    if (dispname || clientalias) rowcount++;
    if (comment) rowcount++;
    if (description) rowcount++;
    if (!newnkconfig && nktime) rowcount++;
    if (downtime) rowcount++;
    if (reporttime) rowcount++;

    fprintf(stdout, "<tr>\n");
    fprintf(stdout, "<th rowspan=%d align=left width=\"25%%\" valign=top>Basics</th>\n", rowcount);
    fprintf(stdout, "<th align=center>%s (%s)</th>\n",
            (dispname ? dispname : host->hostname), bbh_item(hinfo, BBH_IP));
    fprintf(stdout, "</tr>\n");

    if (dispname || clientalias) {
        fprintf(stdout, "<tr><td>Aliases:");
        if (dispname) fprintf(stdout, " %s", dispname);
        if (clientalias) fprintf(stdout, " %s", clientalias);
        fprintf(stdout, "</td></tr>\n");
    }
    if (pagepathtitle) fprintf(stdout, "<tr><td>Monitoring location: %s</td></tr>\n", pagepathtitle);
    if (comment) fprintf(stdout, "<tr><td>Comment: %s</td></tr>\n", comment);
    if (description) fprintf(stdout, "<tr><td>Description: %s</td></tr>\n", description);
    if (!newnkconfig && nktime) fprintf(stdout, "<tr><td>NK monitoring period: %s</td></tr>\n", nktime);
    if (downtime) fprintf(stdout, "<tr><td>Planned downtime: %s</td></tr>\n", downtime);
    if (reporttime) fprintf(stdout, "<tr><td>SLA Reporting Period: %s</td></tr>\n", reporttime);


    /* Build a list of the network tests */
    itm = bbh_item_walk(hinfo);
    while (itm) {
        char *visdata = NULL, *colname = NULL, *expdata = NULL;
        bburl_t bu;
        int dialuptest = 0, reversetest = 0, alwaystruetest = 0, httpextra = 0;

        if (*itm == '?') {
            dialuptest=1;
            itm++;
        }
        if (*itm == '!') {
            reversetest=1;
            itm++;
        }
        if (*itm == '~') {
            alwaystruetest=1;
            itm++;
        }

        if ( argnmatch(itm, "http")         ||
                argnmatch(itm, "content=http") ||
                argnmatch(itm, "cont;http")    ||
                argnmatch(itm, "cont=")        ||
                argnmatch(itm, "nocont;http")  ||
                argnmatch(itm, "nocont=")      ||
                argnmatch(itm, "post;http")    ||
                argnmatch(itm, "post=")        ||
                argnmatch(itm, "nopost;http")  ||
                argnmatch(itm, "nopost=")      ||
                argnmatch(itm, "type;http")    ||
                argnmatch(itm, "type=")        ) {
            visdata = decode_url(itm, &bu);
            colname = bu.columnname;
            if (!colname) {
                if (bu.expdata) {
                    httpextra = 1;
                    if (contidx == 0) {
                        colname = "content";
                        contidx++;
                    }
                    else {
                        sprintf(contcol, "content%d", contidx);
                        colname = contcol;
                        contidx++;
                    }
                }
                else {
                    colname = "http";
                }
            }
            expdata = bu.expdata;
        }
        else if (strncmp(itm, "rpc=", 4) == 0) {
            colname = "rpc";
            visdata = strdup(itm+4);
        }
        else if (strncmp(itm, "dns=", 4) == 0) {
            colname = "dns";
            visdata = strdup(itm+4);
        }
        else if (strncmp(itm, "dig=", 4) == 0) {
            colname = "dns";
            visdata = strdup(itm+4);
        }
        else if (strncmp(itm, pingplus, strlen(pingplus)) == 0) {
            haveping = 1;
            colname = pingcolumn;
            visdata = strdup(itm+strlen(pingplus));
        }
        else if (is_net_test(itm)) {
            colname = strdup(itm);
        }


        if (colname) {
            tag_t *newitem;

addtolist:
            for (newitem = taghead; (newitem && strcmp(newitem->columnname, colname)); newitem = newitem->next);

            if (!newitem) {
                newitem = (tag_t *)calloc(1, sizeof(tag_t));
                newitem->columnname = strdup(colname);
                newitem->visualdata = (visdata ? strdup(visdata) : NULL);
                newitem->expdata = (expdata ? strdup(expdata) : NULL);
                newitem->next = taghead;
                taghead = newitem;
            }
            else {
                /* Multiple tags for one column - must be http */
                newitem->visualdata = (char *)realloc(newitem->visualdata, strlen(newitem->visualdata) + strlen(visdata) + 5);
                strcat(newitem->visualdata, "<br>");
                strcat(newitem->visualdata, visdata);
            }

            if (httpextra) {
                httpextra = 0;
                colname = "http";
                expdata = NULL;
                goto addtolist;
            }
        }

        itm = bbh_item_walk(NULL);
    }

    if (!haveping && !bbh_item(hinfo, BBH_FLAG_NOCONN)) {
        for (testi = 0; (testi < testcount); testi++) {
            if (strcmp(testnames[testi]->name, pingcolumn) == 0) {
                tag_t *newitem = (tag_t *)calloc(1, sizeof(tag_t));
                newitem->columnname = strdup(pingcolumn);
                newitem->next = taghead;
                taghead = newitem;
            }
        }
    }

    /* Add the "badFOO" settings */
    itm = bbh_item_walk(hinfo);
    while (itm) {
        if (strncmp(itm, "bad", 3) == 0) {
            char *tname, *p;
            int b1, b2, b3, n = -1;
            tag_t *tag = NULL;

            tname = itm+3;
            p = strchr(tname, ':');
            if (p) {
                *p = '\0';
                n = sscanf(p+1, "%d:%d:%d", &b1, &b2, &b3);
                for (tag = taghead; (tag && strcmp(tag->columnname, tname)); tag = tag->next);
                *p = ':';
            }

            if (tag && (n == 3)) {
                tag->b1 = b1;
                tag->b2 = b2;
                tag->b3 = b3;
            }
        }

        itm = bbh_item_walk(NULL);
    }

    if (taghead) {
        fprintf(stdout, "<tr>\n");
        fprintf(stdout, "<th align=left valign=top>Network tests");
        if (net) fprintf(stdout, "<br>(from %s)", net);
        fprintf(stdout, "</th>\n");

        fprintf(stdout, "<td><table border=0 cellpadding=\"3\" cellspacing=\"5\" summary=\"%s network tests\">\n", host->hostname);
        fprintf(stdout, "<tr><th align=left valign=top>Service</th><th align=left valign=top>NK</th><th align=left valign=top>C/Y/R limits</th><th align=left valign=top>Specifics</th></tr>\n");
    }
    for (testi = 0, netcount = 0; (testi < testcount); testi++) {
        tag_t *twalk;

        for (twalk = taghead; (twalk && strcasecmp(twalk->columnname, testnames[testi]->name)); twalk = twalk->next);
        if (!twalk) continue;

        use_columndoc(testnames[testi]->name);
        fprintf(stdout, "<tr>");
        fprintf(stdout, "<td valign=top>%s</td>", testnames[testi]->name);
        fprintf(stdout, "<td valign=top>%s</td>", nkval(host->hostname, testnames[testi]->name, nkalerts));

        fprintf(stdout, "<td valign=top>");
        if (twalk->b1 || twalk->b2 || twalk->b3) {
            fprintf(stdout, "%d/%d/%d", twalk->b1, twalk->b2, twalk->b3);
        }
        else {
            fprintf(stdout, "-/-/-");
        }
        fprintf(stdout, "</td>");

        fprintf(stdout, "<td valign=top>");
        fprintf(stdout, "<i>%s</i>", (twalk->visualdata ? twalk->visualdata : "&nbsp;"));
        if (twalk->expdata) fprintf(stdout, " must return <i>'%s'</i>", twalk->expdata);
        fprintf(stdout, "</td>");

        fprintf(stdout, "</tr>");
        netcount++;
    }
    if (taghead) {
        fprintf(stdout, "</table></td>\n");
        fprintf(stdout, "</tr>\n");
    }


    if (netcount != testcount) {
        fprintf(stdout, "<tr>\n");
        fprintf(stdout, "<th align=left valign=top>Local tests</th>\n");
        fprintf(stdout, "<td><table border=0 cellpadding=\"3\" cellspacing=\"5\" summary=\"%s local tests\">\n", host->hostname);
        fprintf(stdout, "<tr><th align=left valign=top>Service</th><th align=left valign=top>NK</th><th align=left valign=top>C/Y/R limits</th><th align=left valign=top>Configuration <i>(NB: Thresholds on client may differ)</i></th></tr>\n");
    }
    for (testi = 0; (testi < testcount); testi++) {
        tag_t *twalk;

        for (twalk = taghead; (twalk && strcasecmp(twalk->columnname, testnames[testi]->name)); twalk = twalk->next);
        if (twalk) continue;

        use_columndoc(testnames[testi]->name);
        fprintf(stdout, "<tr>");
        fprintf(stdout, "<td valign=top>%s</td>", testnames[testi]->name);
        fprintf(stdout, "<td valign=top>%s</td>", nkval(host->hostname, testnames[testi]->name, nkalerts));
        fprintf(stdout, "<td valign=top>-/-/-</td>");

        /* Make up some default configuration data */
        fprintf(stdout, "<td valign=top>");
        if (strcmp(testnames[testi]->name, "cpu") == 0) {
            fprintf(stdout, "UNIX - Yellow: Load average > 1.5, Red: Load average > 3.0<br>");
            fprintf(stdout, "Windows - Yellow: CPU utilisation > 80%%, Red: CPU utilisation > 95%%");
        }
        else if (strcmp(testnames[testi]->name, "disk") == 0) {
            fprintf(stdout, "Default limits: Yellow 90%% full, Red 95%% full<br>\n");
            print_disklist(host->hostname);
        }
        else if (strcmp(testnames[testi]->name, "memory") == 0) {
            fprintf(stdout, "Yellow: swap/pagefile use > 80%%, Red: swap/pagefile use > 90%%");
        }
        else if (strcmp(testnames[testi]->name, "procs") == 0) {
            htnames_t *walk;

            if (!host->procs) fprintf(stdout, "No processes monitored<br>\n");

            for (walk = host->procs; (walk); walk = walk->next) {
                fprintf(stdout, "%s<br>\n", walk->name);
            }
        }
        else if (strcmp(testnames[testi]->name, "svcs") == 0) {
            htnames_t *walk;

            if (!host->svcs) fprintf(stdout, "No services monitored<br>\n");

            for (walk = host->svcs; (walk); walk = walk->next) {
                fprintf(stdout, "%s<br>\n", walk->name);
            }
        }
        else {
            fprintf(stdout, "&nbsp;");
        }
        fprintf(stdout, "</td>");

        fprintf(stdout, "</tr>");
    }
    if (netcount != testcount) {
        fprintf(stdout, "</table></td>\n");
        fprintf(stdout, "</tr>\n");
    }

    /* Do the alerts */
    alert = (activealerts_t *)calloc(1, sizeof(activealerts_t));
    alert->hostname = host->hostname;
    alert->location = bbh_item(hinfo, BBH_ALLPAGEPATHS);
    strcpy(alert->ip, "127.0.0.1");
    alert->color = COL_RED;
    alert->pagemessage = "";
    alert->state = A_PAGING;
    alert->cookie = 12345;
    alert_printmode(2);
    for (testi = 0; (testi < testcount); testi++) {
        alert->testname = testnames[testi]->name;
        if (have_recipient(alert, NULL)) print_alert_recipients(alert, buf);
    }
    xfree(alert);

    if (STRBUFLEN(buf) > 0) {
        fprintf(stdout, "<tr>\n");
        fprintf(stdout, "<th align=left valign=top>Alerts</th>\n");
        fprintf(stdout, "<td><table border=0 cellpadding=\"3\" cellspacing=\"5\" summary=\"%s alerts\">\n", host->hostname);
        fprintf(stdout, "<tr><th>Service</th><th>Recipient</th><th>1st Delay</th><th>Stop after</th><th>Repeat</th><th>Time of Day</th><th>Colors</th></tr>\n");

        fprintf(stdout, "%s", STRBUF(buf));

        fprintf(stdout, "</table></td>\n");
        fprintf(stdout, "</tr>\n");
    }

    /* Finish off this host */
    fprintf(stdout, "</table>\n");

    freestrbuffer(buf);
}
Пример #29
0
int do_external_rrd(char *hostname, char *testname, char *classname, char *pagepaths, char *msg, time_t tstamp) 
{ 
	pid_t childpid;

	dbgprintf("-> do_external(%s, %s)\n", hostname, testname);

	childpid = fork();
	if (childpid == 0) {
		FILE *fd;
		char fn[PATH_MAX];
		enum { R_DEFS, R_FN, R_DATA, R_NEXT } pstate;
		FILE *extfd;
		char extcmd[2*PATH_MAX];
		strbuffer_t *inbuf;
		char *p;
		char **params = NULL;
		int paridx = 0;
		pid_t mypid = getpid();
		
		MEMDEFINE(fn); MEMDEFINE(extcmd);

		sprintf(fn, "%s/rrd_msg_%d", xgetenv("XYMONTMP"), (int) getpid());
		dbgprintf("%09d : Saving msg to file %s\n", (int)mypid, fn);

		fd = fopen(fn, "w");
		if (fd == NULL) {
			errprintf("Cannot create temp file %s\n", fn);
			exit(1);
		}
		if (fwrite(msg, strlen(msg), 1, fd) != 1) {
			errprintf("Error writing to file %s: %s\n", fn, strerror(errno));
			exit(1) ;
		}
		if (fclose(fd)) errprintf("Error closing file %s: %s\n", fn, strerror(errno));

		/* 
		 * Disable the RRD update cache.
		 * We cannot use the cache, because this child
		 * process terminates without flushing the cache,
		 * and it cannot feed the update-data back to the
		 * parent process which owns the cache. So using
		 * an external handler means the updates will be
		 * sync'ed to disk immediately.
		 *
		 * NB: It is OK to do this now and not re-enable it,
		 * since we're running in the external helper
		 * child process - so this only affects the current
		 * update.
		 *
		 * Thanks to Graham Nayler for the analysis.
		 */
		use_rrd_cache = 0;

		inbuf = newstrbuffer(0);

		/* Now call the external helper */
		sprintf(extcmd, "%s %s %s %s", exthandler, hostname, testname, fn);
		dbgprintf("%09d : Calling helper script %s\n", (int)mypid, extcmd);
		extfd = popen(extcmd, "r");
		if (extfd) {
			pstate = R_DEFS;
			initfgets(extfd);

			while (unlimfgets(inbuf, extfd)) {
				p = strchr(STRBUF(inbuf), '\n'); if (p) *p = '\0';
				dbgprintf("%09d : Helper input '%s'\n", (int)mypid, STRBUF(inbuf));
				if (STRBUFLEN(inbuf) == 0) continue;

				if (pstate == R_NEXT) {
					/* After doing one set of data, allow script to re-use the same DS defs */
					if (strncasecmp(STRBUF(inbuf), "DS:", 3) == 0) {
						/* New DS definitions, scratch the old ones */
						if (params) {
							for (paridx=0; (params[paridx] != NULL); paridx++) 
								xfree(params[paridx]);
							xfree(params);
							params = NULL;
						}
						pstate = R_DEFS;
					}
					else pstate = R_FN;
				}

				switch (pstate) {
				  case R_DEFS:
					if (params == NULL) {
						params = (char **)calloc(1, sizeof(char *));
						paridx = 0;
					}

					if (strncasecmp(STRBUF(inbuf), "DS:", 3) == 0) {
						/* Dataset definition */
						params[paridx] = strdup(STRBUF(inbuf));
						paridx++;
						params = (char **)realloc(params, (1 + paridx)*sizeof(char *));
						params[paridx] = NULL;
						break;
					}
					else {
						/* No more DS defs */
						pstate = R_FN;
					}
					/* Fall through */
				  case R_FN:
					setupfn("%s", STRBUF(inbuf));
					pstate = R_DATA;
					break;

				  case R_DATA:
					snprintf(rrdvalues, sizeof(rrdvalues)-1, "%d:%s", (int)tstamp, STRBUF(inbuf));
					rrdvalues[sizeof(rrdvalues)-1] = '\0';
					create_and_update_rrd(hostname, testname, classname, pagepaths, params, NULL);
					pstate = R_NEXT;
					break;

				  case R_NEXT:
					/* Should not happen */
					break;
				}
			}
			pclose(extfd);
		}
		else {
			errprintf("Pipe open of RRD handler failed: %s\n", strerror(errno));
		}

		if (params) {
			for (paridx=0; (params[paridx] != NULL); paridx++) xfree(params[paridx]);
			xfree(params);
		}

		dbgprintf("%09d : Unlinking temp file\n", (int)mypid);
		unlink(fn);
		freestrbuffer(inbuf);

		exit(0);
	}
	else if (childpid > 0) {
		/* Parent continues */
	}
	else {
		errprintf("Fork failed in RRD handler: %s\n", strerror(errno));
	}

	dbgprintf("<- do_external(%s, %s)\n", hostname, testname);
	return 0;
}
Пример #30
0
char *init_tcp_services(void)
{
	static char *xymonnetsvcs = NULL;
	static time_t lastupdate = 0;

	char filename[PATH_MAX];
	struct stat st;
	FILE *fd = NULL;
	strbuffer_t *inbuf;
	svclist_t *head, *tail, *first, *walk;
	char *searchstring;
	int svcnamebytes = 0;
	int svccount = 0;
	int i;

	MEMDEFINE(filename);

	filename[0] = '\0';
	if (xgetenv("XYMONHOME")) {
		sprintf(filename, "%s/etc/", xgetenv("XYMONHOME"));
	}
	strcat(filename, "protocols.cfg");

	if ((stat(filename, &st) == 0) && xymonnetsvcs) {
		/* See if we have already run and the file is unchanged - if so just pickup the result */
		if (st.st_mtime == lastupdate) return xymonnetsvcs;

		/* File has changed - reload configuration. But clean up first so we dont leak memory. */
		if (svcinfo != default_svcinfo) {
			for (i=0; (svcinfo[i].svcname); i++) {
				if (svcinfo[i].svcname) xfree(svcinfo[i].svcname);
				if (svcinfo[i].sendtxt) xfree(svcinfo[i].sendtxt);
				if (svcinfo[i].exptext) xfree(svcinfo[i].exptext);
			}
			xfree(svcinfo);
			svcinfo = default_svcinfo;
		}

		xfree(xymonnetsvcs); xymonnetsvcs = NULL;
	}

	if (xgetenv("XYMONNETSVCS") == NULL) {
		putenv("XYMONNETSVCS=smtp telnet ftp pop pop3 pop-3 ssh imap ssh1 ssh2 imap2 imap3 imap4 pop2 pop-2 nntp");
	}

	fd = fopen(filename, "r");
	if (fd == NULL) {
		errprintf("Cannot open TCP service-definitions file %s - using defaults\n", filename);
		xymonnetsvcs = strdup(xgetenv("XYMONNETSVCS"));

		MEMUNDEFINE(filename);
		return xymonnetsvcs;
	}

	lastupdate = st.st_mtime;
	head = tail = first = NULL;

	inbuf = newstrbuffer(0);
	initfgets(fd);
	while (unlimfgets(inbuf, fd)) {
		char *l, *eol;

		sanitize_input(inbuf, 1, 0);
		l = STRBUF(inbuf);

		if (*l == '[') {
			char *svcname;

			eol = strchr(l, ']'); if (eol) *eol = '\0';
			l = skipwhitespace(l+1);

			svcname = strtok(l, "|"); first = NULL;
			while (svcname) {
				svclist_t *newitem;

				svccount++;
				svcnamebytes += (strlen(svcname) + 1);

				newitem = (svclist_t *) malloc(sizeof(svclist_t));
				newitem->rec = (svcinfo_t *)calloc(1, sizeof(svcinfo_t));
				newitem->rec->svcname = strdup(svcname);
				newitem->next = NULL;

				if (first == NULL) first = newitem;

				if (head == NULL) {
					head = tail = newitem;
				}
				else {
					tail->next = newitem;
					tail = newitem;
				}

				svcname = strtok(NULL, "|");
			}
		}
		else if (strncmp(l, "send ", 5) == 0) {
			if (first) {
				getescapestring(skipwhitespace(l+4), &first->rec->sendtxt, &first->rec->sendlen);
				for (walk = first->next; (walk); walk = walk->next) {
					walk->rec->sendtxt = strdup(first->rec->sendtxt);
					walk->rec->sendlen = first->rec->sendlen;
				}
			}
		}
		else if (strncmp(l, "expect ", 7) == 0) {
			if (first) {
				getescapestring(skipwhitespace(l+6), &first->rec->exptext, &first->rec->explen);
				for (walk = first->next; (walk); walk = walk->next) {
					walk->rec->exptext = strdup(first->rec->exptext);
					walk->rec->explen = first->rec->explen;
					walk->rec->expofs = 0; /* HACK - not used right now */
				}
			}
		}
		else if (strncmp(l, "options ", 8) == 0) {
			if (first) {
				char *opt;

				first->rec->flags = 0;
				l = skipwhitespace(l+7);
				opt = strtok(l, ",");
				while (opt) {
					if      (strcmp(opt, "ssl") == 0)    first->rec->flags |= TCP_SSL;
					else if (strcmp(opt, "banner") == 0) first->rec->flags |= TCP_GET_BANNER;
					else if (strcmp(opt, "telnet") == 0) first->rec->flags |= TCP_TELNET;
					else errprintf("Unknown option: %s\n", opt);

					opt = strtok(NULL, ",");
				}
				for (walk = first->next; (walk); walk = walk->next) {
					walk->rec->flags = first->rec->flags;
				}
			}
		}
		else if (strncmp(l, "port ", 5) == 0) {
			if (first) {
				first->rec->port = atoi(skipwhitespace(l+4));
				for (walk = first->next; (walk); walk = walk->next) {
					walk->rec->port = first->rec->port;
				}
			}
		}
	}

	if (fd) fclose(fd);
	freestrbuffer(inbuf);

	/* Copy from the svclist to svcinfo table */
	svcinfo = (svcinfo_t *) malloc((svccount+1) * sizeof(svcinfo_t));
	for (walk=head, i=0; (walk && (i < svccount)); walk = walk->next, i++) {
		svcinfo[i].svcname = walk->rec->svcname;
		svcinfo[i].sendtxt = walk->rec->sendtxt;
		svcinfo[i].sendlen = walk->rec->sendlen;
		svcinfo[i].exptext = walk->rec->exptext;
		svcinfo[i].explen  = walk->rec->explen;
		svcinfo[i].expofs  = walk->rec->expofs;
		svcinfo[i].flags   = walk->rec->flags;
		svcinfo[i].port    = walk->rec->port;
	}
	memset(&svcinfo[svccount], 0, sizeof(svcinfo_t));

	/* This should not happen */
	if (walk) {
		errprintf("Whoa - didnt copy all services! svccount=%d, next service '%s'\n", 
			svccount, walk->rec->svcname);
	}

	/* Free the temp. svclist list */
	while (head) {
		/*
		 * Note: Dont free the strings inside the records, 
		 * as they are now owned by the svcinfo records.
		 */
		walk = head;
		head = head->next;
		xfree(walk);
	}

	searchstring = strdup(xgetenv("XYMONNETSVCS"));
	xymonnetsvcs = (char *) malloc(strlen(xgetenv("XYMONNETSVCS")) + svcnamebytes + 1);
	strcpy(xymonnetsvcs, xgetenv("XYMONNETSVCS"));
	for (i=0; (svcinfo[i].svcname); i++) {
		char *p;

		strcpy(searchstring, xgetenv("XYMONNETSVCS"));
		p = strtok(searchstring, " ");
		while (p && (strcmp(p, svcinfo[i].svcname) != 0)) p = strtok(NULL, " ");

		if (p == NULL) {
			strcat(xymonnetsvcs, " ");
			strcat(xymonnetsvcs, svcinfo[i].svcname);
		}
	}
	xfree(searchstring);

	if (debug) {
		dump_tcp_services();
		dbgprintf("XYMONNETSVCS set to : %s\n", xymonnetsvcs);
	}

	MEMUNDEFINE(filename);
	return xymonnetsvcs;
}