예제 #1
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);
}
예제 #2
0
파일: do_alert.c 프로젝트: osvaldsson/xymon
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);
}
예제 #3
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);
}
예제 #4
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;
}
예제 #5
0
파일: stackio.c 프로젝트: osvaldsson/xymon
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;
}
예제 #6
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;
}
예제 #7
0
int do_external_rrd(char *hostname, char *testname, 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 = 1;
		pid_t mypid = getpid();
		
		MEMDEFINE(fn); MEMDEFINE(extcmd);

		sprintf(fn, "%s/rrd_msg_%d", xgetenv("BBTMP"), (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));

		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 */
						pstate = R_DEFS;

						if (params) {
							for (paridx=2; (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(8, sizeof(char *));
						params[0] = "rrdcreate";
						params[1] = rrdfn;
						paridx = 1;
					}

					if (strncasecmp(STRBUF(inbuf), "DS:", 3) == 0) {
						/* Dataset definition */
						paridx++;
						params = (char **)realloc(params, (7 + paridx)*sizeof(char *));
						params[paridx] = strdup(STRBUF(inbuf));
						params[paridx+1] = NULL;
						break;
					}
					else {
						/* No more DS defs - put in the RRA's last. */
						params[++paridx] = strdup(rra1);
						params[++paridx] = strdup(rra2);
						params[++paridx] = strdup(rra3);
						params[++paridx] = strdup(rra4);
						params[++paridx] = NULL;
						pstate = R_FN;
					}
					/* Fall through */
				  case R_FN:
					strncpy(rrdfn, STRBUF(inbuf), sizeof(rrdfn)-1);
					rrdfn[sizeof(rrdfn)-1] = '\0';
					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, rrdfn, 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=2; (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;
}
예제 #8
0
/*
 * Load the $HOME/.netrc file with authentication tokens for HTTP tests.
 */
static void load_netrc(void)
{

#define WANT_TOKEN   0
#define MACHINEVAL   1
#define LOGINVAL     2
#define PASSVAL      3
#define OTHERVAL     4

	static int loaded = 0;

	char netrcfn[MAXPATHLEN];
	FILE *fd;
	strbuffer_t *inbuf;
	char *host, *login, *password, *p;
	int state = WANT_TOKEN;

	if (loaded) return;
	loaded = 1;

	MEMDEFINE(netrcfn);

	/* Look for $BBHOME/etc/netrc first, then the default ~/.netrc */
	sprintf(netrcfn, "%s/etc/netrc", xgetenv("BBHOME"));
	fd = fopen(netrcfn, "r");
	/* Can HOME be undefined ? Yes, on Solaris when started during boot */
	if ((fd == NULL) && getenv("HOME")) {
		sprintf(netrcfn, "%s/.netrc", xgetenv("HOME"));
		fd = fopen(netrcfn, "r");
	}

	if (fd == NULL) {
		MEMUNDEFINE(netrcfn);
		return;
	}

	host = login = password = NULL;
	initfgets(fd);
	inbuf = newstrbuffer(0);
	while (unlimfgets(inbuf, fd)) {
		sanitize_input(inbuf, 0, 0);

		if (STRBUFLEN(inbuf) != 0) {
			p = strtok(STRBUF(inbuf), " \t");
			while (p) {
				switch (state) {
				  case WANT_TOKEN:
					if (strcmp(p, "machine") == 0) state = MACHINEVAL;
					else if (strcmp(p, "login") == 0) state = LOGINVAL;
					else if (strcmp(p, "password") == 0) state = PASSVAL;
					else if (strcmp(p, "account") == 0) state = OTHERVAL;
					else if (strcmp(p, "macdef") == 0) state = OTHERVAL;
					else if (strcmp(p, "default") == 0) { host = ""; state = WANT_TOKEN; }
					else state = WANT_TOKEN;
					break;

				  case MACHINEVAL:
					host = strdup(p); state = WANT_TOKEN; break;

				  case LOGINVAL:
					login = strdup(p); state = WANT_TOKEN; break;

				  case PASSVAL:
					password = strdup(p); state = WANT_TOKEN; break;

				  case OTHERVAL:
				  	state = WANT_TOKEN; break;
				}

				if (host && login && password) {
					loginlist_t *item = (loginlist_t *) malloc(sizeof(loginlist_t));

					item->host = host;
					item->auth = (char *) malloc(strlen(login) + strlen(password) + 2);
					sprintf(item->auth, "%s:%s", login, password);
					item->next = loginhead;
					loginhead = item;
					host = login = password = NULL;
				}

				p = strtok(NULL, " \t");
			}
		}
	}

	fclose(fd);
	freestrbuffer(inbuf);

	MEMUNDEFINE(netrcfn);
}
예제 #9
0
void load_checkpoint(char *filename)
{
	char *subfn;
	FILE *fd;
	strbuffer_t *inbuf;
	char statuscmd[1024];
	char *statusbuf = NULL;
	sendreturn_t *sres;

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

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

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

		sanitize_input(inbuf, 0, 0);

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

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

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

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

			if (statusbuf) {
				char *key;

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

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

	subfn = (char *)malloc(strlen(filename)+5);
	sprintf(subfn, "%s.sub", filename);
	load_state(subfn, statusbuf);
	xfree(subfn);
	if (statusbuf) xfree(statusbuf);
}
예제 #10
0
int main(int argc, char *argv[])
{
	strbuffer_t *inbuf;
	char *ackbuf;
	char *subjectline = NULL;
	char *returnpathline = NULL;
	char *fromline = NULL;
	char *firsttxtline = NULL;
	int inheaders = 1;
	char *p;
	pcre *subjexp;
	const char *errmsg;
	int errofs, result;
	int ovector[30];
	char cookie[10];
	int duration = 0;
	int argi;
	char *envarea = NULL;

	for (argi=1; (argi < argc); argi++) {
		if (strcmp(argv[argi], "--debug") == 0) {
			debug = 1;
		}
		else if (argnmatch(argv[argi], "--env=")) {
			char *p = strchr(argv[argi], '=');
			loadenv(p+1, envarea);
		}
		else if (argnmatch(argv[argi], "--area=")) {
			char *p = strchr(argv[argi], '=');
			envarea = strdup(p+1);
		}
	}

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

		if (!inheaders) {
			/* We're in the message body. Look for a "delay=N" line here. */
			if ((strncasecmp(STRBUF(inbuf), "delay=", 6) == 0) || (strncasecmp(STRBUF(inbuf), "delay ", 6) == 0)) {
				duration = durationvalue(STRBUF(inbuf)+6);
				continue;
			}
			else if ((strncasecmp(STRBUF(inbuf), "ack=", 4) == 0) || (strncasecmp(STRBUF(inbuf), "ack ", 4) == 0)) {
				/* Some systems cannot generate a subject. Allow them to ack
				 * via text in the message body. */
				subjectline = (char *)malloc(STRBUFLEN(inbuf) + 1024);
				sprintf(subjectline, "Subject: Xymon [%s]", STRBUF(inbuf)+4);
			}
			else if (*STRBUF(inbuf) && !firsttxtline) {
				/* Save the first line of the message body, but ignore blank lines */
				firsttxtline = strdup(STRBUF(inbuf));
			}

			continue;	/* We don't care about the rest of the message body */
		}

		/* See if we're at the end of the mail headers */
		if (inheaders && (STRBUFLEN(inbuf) == 0)) { inheaders = 0; continue; }

		/* Is it one of those we want to keep ? */
		if (strncasecmp(STRBUF(inbuf), "return-path:", 12) == 0) returnpathline = strdup(skipwhitespace(STRBUF(inbuf)+12));
		else if (strncasecmp(STRBUF(inbuf), "from:", 5) == 0)    fromline = strdup(skipwhitespace(STRBUF(inbuf)+5));
		else if (strncasecmp(STRBUF(inbuf), "subject:", 8) == 0) subjectline = strdup(skipwhitespace(STRBUF(inbuf)+8));
	}
	freestrbuffer(inbuf);

	/* No subject ? No deal */
	if (subjectline == NULL) {
		dbgprintf("Subject-line not found\n");
		return 1;
	}

	/* Get the alert cookie */
	subjexp = pcre_compile(".*(Xymon|Hobbit|BB)[ -]* \\[*(-*[0-9]+)[\\]!]*", PCRE_CASELESS, &errmsg, &errofs, NULL);
	if (subjexp == NULL) {
		dbgprintf("pcre compile failed - 1\n");
		return 2;
	}
	result = pcre_exec(subjexp, NULL, subjectline, strlen(subjectline), 0, 0, ovector, (sizeof(ovector)/sizeof(int)));
	if (result < 0) {
		dbgprintf("Subject line did not match pattern\n");
		return 3; /* Subject did not match what we expected */
	}
	if (pcre_copy_substring(subjectline, ovector, result, 2, cookie, sizeof(cookie)) <= 0) {
		dbgprintf("Could not find cookie value\n");
		return 4; /* No cookie */
	}
	pcre_free(subjexp);

	/* See if there's a "DELAY=" delay-value also */
	subjexp = pcre_compile(".*DELAY[ =]+([0-9]+[mhdw]*)", PCRE_CASELESS, &errmsg, &errofs, NULL);
	if (subjexp == NULL) {
		dbgprintf("pcre compile failed - 2\n");
		return 2;
	}
	result = pcre_exec(subjexp, NULL, subjectline, strlen(subjectline), 0, 0, ovector, (sizeof(ovector)/sizeof(int)));
	if (result >= 0) {
		char delaytxt[4096];
		if (pcre_copy_substring(subjectline, ovector, result, 1, delaytxt, sizeof(delaytxt)) > 0) {
			duration = durationvalue(delaytxt);
		}
	}
	pcre_free(subjexp);

	/* See if there's a "msg" text also */
	subjexp = pcre_compile(".*MSG[ =]+(.*)", PCRE_CASELESS, &errmsg, &errofs, NULL);
	if (subjexp == NULL) {
		dbgprintf("pcre compile failed - 3\n");
		return 2;
	}
	result = pcre_exec(subjexp, NULL, subjectline, strlen(subjectline), 0, 0, ovector, (sizeof(ovector)/sizeof(int)));
	if (result >= 0) {
		char msgtxt[4096];
		if (pcre_copy_substring(subjectline, ovector, result, 1, msgtxt, sizeof(msgtxt)) > 0) {
			firsttxtline = strdup(msgtxt);
		}
	}
	pcre_free(subjexp);

	/* Use the "return-path:" header if we didn't see a From: line */
	if ((fromline == NULL) && returnpathline) fromline = returnpathline;
	if (fromline) {
		/* Remove '<' and '>' from the fromline - they mess up HTML */
		while ((p = strchr(fromline, '<')) != NULL) *p = ' ';
		while ((p = strchr(fromline, '>')) != NULL) *p = ' ';
	}

	/* Setup the acknowledge message */
	if (duration == 0) duration = 60;	/* Default: Ack for 60 minutes */
	if (firsttxtline == NULL) firsttxtline = "<No cause specified>";
	ackbuf = (char *)malloc(4096 + strlen(firsttxtline) + (fromline ? strlen(fromline) : 0));
	p = ackbuf;
	p += sprintf(p, "xymondack %s %d %s", cookie, duration, firsttxtline);
	if (fromline) {
		p += sprintf(p, "\nAcked by: %s", fromline);
	}

	if (debug) {
		printf("%s\n", ackbuf);
		return 0;
	}

	sendmessage(ackbuf, NULL, XYMON_TIMEOUT, NULL);
	return 0;
}
예제 #11
0
static void loadtests(void)
{
	static time_t lastupdate = 0;
	static char *fn = NULL;
	struct stat st;
	FILE *fd;
	strbuffer_t *inbuf;

	if (!fn) {
		fn = (char *)malloc(1024 + strlen(xgetenv("XYMONHOME")));
		*fn = '\0';
	}

	sprintf(fn, "%s/etc/combo.cfg", xgetenv("XYMONHOME"));
	if ((stat(fn, &st) == 0) && (st.st_mtime == lastupdate)) return;
	lastupdate = st.st_mtime;

	fd = fopen(fn, "r");
	if (fd == NULL) {
		errprintf("Cannot open %s/combo.cfg\n", xgetenv("XYMONHOME"));
		*fn = '\0';
		return;
	}

	flush_testlist();

	initfgets(fd);
	inbuf = newstrbuffer(0);
	while (unlimfgets(inbuf, fd)) {
		char *p, *comment;
		char *inp, *outp;

		p = strchr(STRBUF(inbuf), '\n'); if (p) *p = '\0';
		/* Strip whitespace */
		for (inp=outp=STRBUF(inbuf); ((*inp >= ' ') && (*inp != '#')); inp++) {
			if (isspace((int)*inp)) {
			}
			else {
				*outp = *inp;
				outp++;
			}
		}
		*outp = '\0';
		if (strlen(inp)) memmove(outp, inp, strlen(inp)+1);
		strbufferrecalc(inbuf);

		if (STRBUFLEN(inbuf) && (*STRBUF(inbuf) != '#') && (p = strchr(STRBUF(inbuf), '=')) ) {
			testspec_t *newtest;
			char *hname, *tname;

			hname = gethname(STRBUF(inbuf));
			tname = gettname(STRBUF(inbuf));

			if (hname && tname) {
				*p = '\0';
				comment = strchr(p+1, '#');
				if (comment) *comment = '\0';
				newtest = (testspec_t *) malloc(sizeof(testspec_t));
				newtest->reshostname = strdup(gethname(STRBUF(inbuf)));
				newtest->restestname = strdup(gettname(STRBUF(inbuf)));
				newtest->expression = strdup(p+1);
				newtest->comment = (comment ? strdup(comment+1) : NULL);
				newtest->resultexpr = NULL;
				newtest->valuelist = NULL;
				newtest->result = -1;
				newtest->errbuf = NULL;
				newtest->next = testhead;
				testhead = newtest;
				testcount++;
			}
			else {
				errprintf("Invalid combo test %s - missing host/test names. Perhaps you need to escape dashes?\n", STRBUF(inbuf));
			}
		}
	}

	fclose(fd);
	freestrbuffer(inbuf);
}